M17idd commited on
Commit
9e2b7fb
·
1 Parent(s): 6536df1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -248
app.py CHANGED
@@ -1,191 +1,92 @@
1
- import time
2
  import streamlit as st
3
- from langchain.document_loaders import PyPDFLoader
4
- from langchain.text_splitter import RecursiveCharacterTextSplitter
5
- from langchain.embeddings.base import Embeddings
 
6
  from langchain.vectorstores import FAISS
7
- from langchain.indexes import VectorstoreIndexCreator
8
- from langchain.chains import RetrievalQA
9
  from langchain.chat_models import ChatOpenAI
10
- from typing import List
11
- from together import Together
12
- import pandas as pd
13
- from langchain.docstore.document import Document
14
 
15
- st.set_page_config(page_title="رزم یار ارتش", page_icon="🪖", layout="wide")
 
16
 
17
  # ----------------- استایل سفارشی -----------------
18
- st.markdown("""
19
  <style>
20
  @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap');
 
21
  html, body, [class*="css"] {
22
  font-family: 'Vazirmatn', Tahoma, sans-serif;
23
  direction: rtl;
24
  text-align: right;
25
  }
 
26
  .stApp {
27
- background: linear-gradient(to left, #f0f4f7, #d9e2ec);
28
- }
29
- .sidebar .sidebar-content {
30
- background-color: #ffffff;
31
- border-left: 2px solid #4e8a3e;
32
- padding-top: 10px;
33
- }
34
- .sidebar .sidebar-content div {
35
- margin-bottom: 10px;
36
- font-weight: bold;
37
- color: #2c3e50;
38
- font-size: 15px;
39
- }
40
- .stButton>button {
41
- background-color: #4e8a3e !important;
42
- color: white !important;
43
- font-weight: bold;
44
- border-radius: 8px;
45
- padding: 5px 16px;
46
- transition: 0.3s;
47
- font-size: 14px;
48
- }
49
- .stButton>button:hover {
50
- background-color: #3c6d30 !important;
51
- }
52
- .header-text {
53
- text-align: center;
54
- margin-top: 15px;
55
- margin-bottom: 25px;
56
- background-color: rgba(255, 255, 255, 0.85);
57
- padding: 16px;
58
- border-radius: 16px;
59
- box-shadow: 0 4px 10px rgba(0,0,0,0.1);
60
- }
61
- .header-text h1 {
62
- font-size: 36px;
63
- color: #2c3e50;
64
- margin: 0;
65
- font-weight: bold;
66
- }
67
- .subtitle {
68
- font-size: 16px;
69
- color: #34495e;
70
- margin-top: 5px;
71
- }
72
- .chat-message {
73
- background-color: rgba(255, 255, 255, 0.95);
74
- border: 1px solid #4e8a3e;
75
- border-radius: 12px;
76
- padding: 14px;
77
- margin-bottom: 10px;
78
- box-shadow: 0 4px 8px rgba(0,0,0,0.08);
79
- animation: fadeIn 0.5s ease;
80
- }
81
- .stTextInput>div>input, .stTextArea textarea {
82
- background-color: rgba(255,255,255,0.9) !important;
83
- border-radius: 8px !important;
84
- direction: rtl;
85
- text-align: right;
86
- font-family: 'Vazirmatn', Tahoma;
87
- }
88
- img.small-logo {
89
- width: 90px;
90
- margin-bottom: 15px;
91
- display: block;
92
- margin-right: auto;
93
- margin-left: auto;
94
- }
95
- .menu-item {
96
- display: flex;
97
- align-items: center;
98
- gap: 8px;
99
- padding: 6px 0;
100
- font-size: 15px;
101
- cursor: pointer;
102
- }
103
- .menu-item img {
104
- width: 20px;
105
- height: 20px;
106
  }
 
107
  </style>
108
  """, unsafe_allow_html=True)
109
 
110
- # ----------------- بدنه اصلی -----------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  with st.sidebar:
112
- st.image("log.png", width=90)
113
-
114
 
115
- st.markdown("""
116
- <div class="menu-item">
117
- <img src="https://cdn-icons-png.flaticon.com/512/3596/3596165.png" />
118
- گفتگوی جدید
119
- </div>
120
- <div class="menu-item">
121
- <img src="https://cdn-icons-png.flaticon.com/512/709/709496.png" />
122
- تاریخچه
123
- </div>
124
- <hr/>
125
- <div class="menu-item">
126
- <img src="https://cdn-icons-png.flaticon.com/512/1828/1828932.png" />
127
- مدل‌های هوش مصنوعی
128
- </div>
129
- <div class="menu-item">
130
- <img src="https://cdn-icons-png.flaticon.com/512/681/681494.png" />
131
- تولید محتوا
132
- </div>
133
- <hr/>
134
- <div class="menu-item">
135
- <img src="https://cdn-icons-png.flaticon.com/512/3601/3601646.png" />
136
- دستیار ویژه
137
- </div>
138
- <div class="menu-item">
139
- <img src="https://cdn-icons-png.flaticon.com/512/709/709612.png" />
140
- ابزار مالی
141
- </div>
142
- <hr/>
143
- <div class="menu-item">
144
- <img src="https://cdn-icons-png.flaticon.com/512/2099/2099058.png" />
145
- تنظیمات
146
- </div>
147
- <div class="menu-item">
148
- <img src="https://cdn-icons-png.flaticon.com/512/597/597177.png" />
149
- پشتیبانی
150
- </div>
151
- """, unsafe_allow_html=True)
152
- st.markdown("""
153
- <style>
154
- /* تنظیم سایز سایدبار */
155
- [data-testid="stSidebar"] {
156
- width: 220px !important;
157
- flex-shrink: 0;
158
- }
159
- [data-testid="stSidebar"] > div {
160
- width: 220px !important;
161
- }
162
- </style>
163
- """, unsafe_allow_html=True)
164
-
165
- # محتوای اصلی
166
  st.markdown("""
167
  <div class="header-text">
168
- <h1>رزم یار ارتش</h1>
169
- <div class="subtitle">دستیار هوشمند ارتشی برای پشتیبانی و راهبری</div>
170
  </div>
171
  """, unsafe_allow_html=True)
172
 
173
- st.markdown('<div class="chat-message">👋 سلام! چطور میتونم کمکتون کنم؟</div>', unsafe_allow_html=True)
174
-
175
- # چت اینپوت کاربر
176
- #user_input = st.text_input("پیام خود را وارد کنید...")
177
-
178
- #if user_input:
179
- # st.markdown(f'<div class="chat-message">📩 شما: {user_input}</div>', unsafe_allow_html=True)
180
-
181
-
182
-
183
-
184
-
185
-
186
-
187
 
188
- # ----------- تعریف کلاس امبدینگ با Together -----------
189
  class TogetherEmbeddings(Embeddings):
190
  def __init__(self, model_name: str, api_key: str):
191
  self.model_name = model_name
@@ -204,7 +105,7 @@ class TogetherEmbeddings(Embeddings):
204
  return self.embed_documents([text])[0]
205
 
206
 
207
- # ----------- پردازش و ایندکس کردن CSV -----------
208
  @st.cache_resource
209
  def build_vectorstore_from_csv(csv_file_path: str):
210
  df = pd.read_csv(csv_file_path)
@@ -226,119 +127,61 @@ def build_vectorstore_from_csv(csv_file_path: str):
226
 
227
  embeddings = TogetherEmbeddings(
228
  model_name="togethercomputer/m2-bert-80M-32k-retrieval",
229
- api_key="0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979"
230
- )
231
 
232
  vectorstore = FAISS.from_documents(documents, embeddings)
233
  return vectorstore, embeddings
234
 
235
 
236
- # ----------- بارگذاری مدل زبانی -----------
237
  def load_llm():
238
  return ChatOpenAI(
239
  base_url="https://api.together.xyz/v1",
240
  api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
241
- model="Qwen/Qwen3-235B-A22B-fp8-tput"
242
  )
243
 
244
 
245
- # ----------- ساخت پرامپت نهایی برای LLM -----------
246
- def build_prompt(context: str, user_question: str) -> str:
247
- return f"""با توجه به اطلاعات زیر، فقط بر اساس آن‌ها به سؤال پاسخ بده. اگر اطلاعات کافی نیست، بگو اطلاعات کافی ندارم.
248
- 🔹 اطلاعات:\n{context}\n\n❓ سؤال: {user_question}
249
- """
250
-
251
-
252
- # ----------- تمیز کردن خروجی مدل از پاسخ‌های اضافی -----------
253
- def clean_llm_response(response_text: str) -> str:
254
- lines = response_text.split('\n')
255
- filtered = [
256
- line for line in lines
257
- if not line.strip().startswith("<")
258
- and not line.strip().lower().startswith(("think", "note", "#"))
259
- ]
260
- return "\n".join(filtered).strip() or "متأسفم، اطلاعات دقیقی در این مورد ندارم."
261
-
262
-
263
- # ----------- پردازش سوال و بازیابی پاسخ‌ها -----------
264
  def process_user_query(query: str, vectorstore, embedding_model, llm):
265
- # 1. ساخت embedding از سوال
266
  query_embedding = embedding_model.embed_query(query)
267
-
268
- # 2. پیدا کردن 3 پاسخ مشابه با cosine similarity
269
  docs = vectorstore.similarity_search_by_vector(query_embedding, k=3)
270
  context = "\n".join([doc.page_content for doc in docs])
271
 
272
- # 3. ساخت پرامپت نهایی با استفاده از پاسخ‌های مشابه به عنوان context
273
- final_prompt = build_prompt(context, query)
274
-
275
- # 4. ارسال پرامپت به LLM و دریافت پاسخ
276
  response = llm.invoke(final_prompt)
277
  raw_answer = response.content.strip()
278
 
279
- # 5. تمیز کردن و نمایش پاسخ نهایی
280
- clean_answer = clean_llm_response(raw_answer)
281
  return clean_answer
282
 
283
 
284
- # ----------- اجرای Streamlit UI -----------
285
  def run_chat_ui():
286
  csv_file_path = 'output (1).csv'
287
  try:
288
  vectorstore, embedding_model = build_vectorstore_from_csv(csv_file_path)
289
  except Exception as e:
290
  st.error(f"خطا در پردازش فایل: {str(e)}")
291
- st.stop()
292
-
293
  llm = load_llm()
294
 
295
- if 'messages' not in st.session_state:
296
- st.session_state.messages = []
297
-
298
- if 'pending_prompt' not in st.session_state:
299
- st.session_state.pending_prompt = None
300
-
301
- # نمایش پیام‌های قبلی
302
- for msg in st.session_state.messages:
303
- with st.chat_message(msg['role']):
304
- st.markdown(f"{msg['content']}", unsafe_allow_html=True)
305
-
306
- # گرفتن سوال جدید
307
- user_prompt = st.chat_input("سوال خود را وارد کنید...")
308
-
309
- if user_prompt:
310
- st.session_state.messages.append({'role': 'user', 'content': user_prompt})
311
- st.session_state.pending_prompt = user_prompt
312
- st.rerun()
313
-
314
- # پردازش سوال
315
- if st.session_state.pending_prompt:
316
- with st.chat_message("ai"):
317
- thinking = st.empty()
318
- thinking.markdown("🤖 در حال فکر کردن...")
319
-
320
- try:
321
- # پردازش سوال و دریافت پاسخ نهایی
322
- query = st.session_state.pending_prompt
323
- clean_answer = process_user_query(query, vectorstore, embedding_model, llm)
324
-
325
- thinking.empty()
326
- full_response = ""
327
- placeholder = st.empty()
328
- for word in clean_answer.split():
329
- full_response += word + " "
330
- placeholder.markdown(full_response + "▌")
331
- time.sleep(0.03)
332
-
333
- placeholder.markdown(full_response)
334
- st.session_state.messages.append({'role': 'ai', 'content': full_response})
335
- st.session_state.pending_prompt = None
336
-
337
- except Exception as e:
338
- thinking.empty()
339
- st.error(f"خطا در پردازش مدل: {str(e)}")
340
-
341
-
342
- # اجرای برنامه
343
- if __name__ == "__main__":
344
- run_chat_ui()
 
 
1
  import streamlit as st
2
+ import datetime
3
+ import pandas as pd
4
+ from typing import List
5
+ from langchain.embeddings import Embeddings
6
  from langchain.vectorstores import FAISS
7
+ from langchain.prompts import ChatPromptTemplate
 
8
  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
+
21
  html, body, [class*="css"] {
22
  font-family: 'Vazirmatn', Tahoma, sans-serif;
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
 
35
+ # ----------------- احراز هویت ساده -----------------
36
+ if "authenticated" not in st.session_state:
37
+ st.session_state.authenticated = False
38
+
39
+ if not st.session_state.authenticated:
40
+ st.markdown("<h3 style='text-align: center; color: #b8860b;'>ورود به رزم‌یار ارتش</h3>", unsafe_allow_html=True)
41
+ username = st.text_input("نام کاربری:", placeholder="شناسه نظامی خود را وارد کنید")
42
+ password = st.text_input("رمز عبور:", type="password", placeholder="رمز عبور نظامی")
43
+ if st.button("ورود"):
44
+ if username == "admin" and password == "123":
45
+ st.session_state.authenticated = True
46
+ st.rerun()
47
+ else:
48
+ st.error("نام کاربری یا رمز عبور اشتباه است.")
49
+ st.stop()
50
+
51
+ # ----------------- سایدبار -----------------
52
  with st.sidebar:
53
+ st.image("log.png", use_container_width=True)
 
54
 
55
+ menu_items = [
56
+ ("گزارش عملیاتی", "https://cdn-icons-png.flaticon.com/512/3596/3596165.png"),
57
+ ("تاریخچه ماموریت‌ها", "https://cdn-icons-png.flaticon.com/512/709/709496.png"),
58
+ ("تحلیل داده‌های نظامی", "https://cdn-icons-png.flaticon.com/512/1828/1828932.png"),
59
+ ("مدیریت منابع", "https://cdn-icons-png.flaticon.com/512/681/681494.png"),
60
+ ("دستیار فرماندهی", "https://cdn-icons-png.flaticon.com/512/3601/3601646.png"),
61
+ ("تنظیمات امنیتی", "https://cdn-icons-png.flaticon.com/512/2099/2099058.png"),
62
+ ("پشتیبانی فنی", "https://cdn-icons-png.flaticon.com/512/597/597177.png"),
63
+ ]
64
+
65
+ for idx, (text, icon) in enumerate(menu_items):
66
+ st.markdown(f"""
67
+ <div class="menu-item">
68
+ <img src="{icon}" />
69
+ {text}
70
+ </div>
71
+ """, unsafe_allow_html=True)
72
+
73
+ # ----------------- محتوای اصلی -----------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  st.markdown("""
75
  <div class="header-text">
76
+ <h1>رزم‌یار ارتش</h1>
77
+ <div class="subtitle">دستیار هوشمند ارتش</div>
78
  </div>
79
  """, unsafe_allow_html=True)
80
 
81
+ # پیام خوش‌آمدگویی
82
+ st.markdown(f"""
83
+ <div class="chat-message">
84
+ <span style="font-size: 24px;">🪖</span>
85
+ <span>به رزم‌یار ارتش خوش آمدید.</span>
86
+ </div>
87
+ """, unsafe_allow_html=True)
 
 
 
 
 
 
 
88
 
89
+ # ----------------- کلاس توگدر امبدینگ -----------------
90
  class TogetherEmbeddings(Embeddings):
91
  def __init__(self, model_name: str, api_key: str):
92
  self.model_name = model_name
 
105
  return self.embed_documents([text])[0]
106
 
107
 
108
+ # ----------- پردازش و ایندکس کردن CSV -----------
109
  @st.cache_resource
110
  def build_vectorstore_from_csv(csv_file_path: str):
111
  df = pd.read_csv(csv_file_path)
 
127
 
128
  embeddings = TogetherEmbeddings(
129
  model_name="togethercomputer/m2-bert-80M-32k-retrieval",
130
+ api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979'
131
+ )
132
 
133
  vectorstore = FAISS.from_documents(documents, embeddings)
134
  return vectorstore, embeddings
135
 
136
 
137
+ # ----------- بارگذاری مدل زبانی -----------
138
  def load_llm():
139
  return ChatOpenAI(
140
  base_url="https://api.together.xyz/v1",
141
  api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
142
+ model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free"
143
  )
144
 
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
+ """
 
155
  response = llm.invoke(final_prompt)
156
  raw_answer = response.content.strip()
157
 
158
+ clean_answer = raw_answer.strip() or "متأسفم، اطلاعات دقیقی در این مورد ندارم."
 
159
  return clean_answer
160
 
161
 
162
+ # ----------- اجرای Streamlit UI -----------
163
  def run_chat_ui():
164
  csv_file_path = 'output (1).csv'
165
  try:
166
  vectorstore, embedding_model = build_vectorstore_from_csv(csv_file_path)
167
  except Exception as e:
168
  st.error(f"خطا در پردازش فایل: {str(e)}")
169
+ return
170
+
171
  llm = load_llm()
172
 
173
+ # فرم ورودی و دکمه‌ها
174
+ with st.form(key="chat_form"):
175
+ user_input = st.text_area("دستور یا پرس‌وجو:", height=120, placeholder="ماموریت یا سوال خود را وارد کنید...")
176
+ submit_button = st.form_submit_button("ارسال دستور")
177
+
178
+ if submit_button and user_input:
179
+ response = process_user_query(user_input, vectorstore, embedding_model, llm)
180
+ st.markdown(f"""
181
+ <div class="chat-message">
182
+ <span style="font-size: 24px;">🎖️</span>
183
+ <span>{response}</span>
184
+ </div>
185
+ """, unsafe_allow_html=True)
186
+
187
+ run_chat_ui()