sivan22 commited on
Commit
165cf08
·
verified ·
1 Parent(s): 82e40a3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +255 -275
app.py CHANGED
@@ -1,275 +1,255 @@
1
- import streamlit as st
2
- from tantivy_search_agent import TantivySearchAgent
3
- from agent_workflow import SearchAgent
4
- import os
5
- from typing import Optional, List
6
- from dotenv import load_dotenv
7
- import gdown
8
-
9
- # Load environment variables
10
- load_dotenv()
11
-
12
- class SearchAgentUI:
13
- def __init__(self):
14
- self.tantivy_agent: Optional[TantivySearchAgent] = None
15
- self.agent: Optional[SearchAgent] = None
16
- self.index_path ="./index" # os.getenv("INDEX_PATH", "./index")
17
- # Google Drive folder ID for the index
18
- self.gdrive_index_id = os.getenv("GDRIVE_INDEX_ID", "1lpbBCPimwcNfC0VZOlQueA4SHNGIp5_t")
19
-
20
- def download_index_from_gdrive(self) -> bool:
21
- """Download index folder from Google Drive"""
22
- try:
23
- # Create a temporary zip file path
24
- zip_path = "index.zip"
25
- # Download the folder as a zip file
26
- url = f"https://drive.google.com/uc?id={self.gdrive_index_id}"
27
-
28
- # Create a progress bar and status text
29
- progress_text = st.empty()
30
- progress_bar = st.progress(0)
31
-
32
- def progress_callback(progress):
33
- progress_bar.progress(progress)
34
- progress_text.text(f"מוריד... {progress:.1f}%")
35
-
36
- # Download with progress callback
37
- gdown.download(url, zip_path, quiet=False, callback=progress_callback)
38
-
39
- # Update status for extraction
40
- progress_text.text("מחלץ קבצים...")
41
- progress_bar.progress(100)
42
-
43
- # Extract the zip file
44
- import zipfile
45
- with zipfile.ZipFile(zip_path, 'r') as zip_ref:
46
- zip_ref.extractall(".")
47
-
48
- # Remove the zip file
49
- os.remove(zip_path)
50
-
51
- # Clear the progress indicators
52
- progress_text.empty()
53
- progress_bar.empty()
54
-
55
- return True
56
- except Exception as e:
57
- st.error(f"Failed to download index: {str(e)}")
58
- return False
59
-
60
- def get_available_providers(self) -> List[str]:
61
- """Get available providers without creating a SearchAgent instance"""
62
- temp_tantivy = TantivySearchAgent(self.index_path)
63
- temp_agent = SearchAgent(temp_tantivy)
64
- return temp_agent.get_available_providers()
65
-
66
- def initialize_system(self):
67
- try:
68
- # Check if index folder exists
69
- if not os.path.exists(self.index_path):
70
- st.warning("Index folder not found. Attempting to download from Google Drive...")
71
- if not self.download_index_from_gdrive():
72
- return False, "שגיאה: לא ניתן להוריד את האינדקס", []
73
- st.success("Index downloaded successfully!")
74
-
75
- self.tantivy_agent = TantivySearchAgent(self.index_path)
76
- if self.tantivy_agent.validate_index():
77
- available_providers = self.get_available_providers()
78
- self.agent = SearchAgent(
79
- self.tantivy_agent,
80
- provider_name=st.session_state.get('provider', available_providers[0])
81
- )
82
- return True, "המערכת מוכנה לחיפוש", available_providers
83
- else:
84
- return False, "שגיאה: אינדקס לא תקין", []
85
- except Exception as ex:
86
- return False, f"שגיאה באתחול המערכת: {str(ex)}", []
87
-
88
- def main(self):
89
- st.set_page_config(
90
- page_title="איתוריא",
91
- layout="wide",
92
- initial_sidebar_state="collapsed"
93
- )
94
-
95
- # Enhanced RTL support and styling
96
- st.markdown("""
97
- <style>
98
- .stApp {
99
- direction: rtl;
100
- }
101
- .stTextInput > div > div > input {
102
- direction: rtl;
103
- }
104
- .stSelectbox > div > div > div {
105
- direction: rtl;
106
- }
107
- .stNumberInput > div > div > input {
108
- direction: rtl;
109
- }
110
- .search-step {
111
- border: 1px solid #e0e0e0;
112
- border-radius: 5px;
113
- padding: 10px;
114
- margin: 5px 0;
115
- background-color: #f8f9fa;
116
- }
117
- .document-group {
118
- border: 1px solid #e3f2fd;
119
- border-radius: 5px;
120
- padding: 10px;
121
- margin: 5px 0;
122
- background-color: #f5f9ff;
123
- }
124
- .document-item {
125
- border: 1px solid #e0e0e0;
126
- border-radius: 5px;
127
- padding: 10px;
128
- margin: 5px 0;
129
- background-color: white;
130
- }
131
- </style>
132
- """, unsafe_allow_html=True)
133
-
134
- # Initialize system
135
- success, status_msg, available_providers = self.initialize_system()
136
-
137
- # Header layout
138
- col1, col2, col3 = st.columns([2,1,1])
139
-
140
- with col1:
141
- if success:
142
- st.success(status_msg)
143
- else:
144
- st.error(status_msg)
145
-
146
- with col2:
147
- if 'provider' not in st.session_state:
148
- st.session_state.provider = available_providers[0] if available_providers else None
149
-
150
- if available_providers:
151
- provider = st.selectbox(
152
- "ספק בינה מלאכותית",
153
- options=available_providers,
154
- key='provider'
155
- )
156
- if self.agent:
157
- self.agent.set_provider(provider)
158
-
159
- with col3:
160
- col3_1, col3_2 = st.columns(2)
161
- with col3_1:
162
- max_iterations = st.number_input(
163
- "מספר נסיונות מקסימלי",
164
- min_value=1,
165
- value=3,
166
- key='max_iterations'
167
- )
168
- with col3_2:
169
- results_per_search = st.number_input(
170
- "תוצאות לכל חיפוש",
171
- min_value=1,
172
- value=5,
173
- key='results_per_search'
174
- )
175
-
176
- # Search input
177
- query = st.text_input(
178
- "הכנס שאילתת חיפוש",
179
- disabled=not success,
180
- placeholder="הקלד את שאילתת החיפוש שלך כאן...",
181
- key='search_query'
182
- )
183
-
184
- # Search button
185
- if (st.button('חפש', disabled=not success) or query) and query!="" and self.agent:
186
- try:
187
- if 'steps' not in st.session_state:
188
- st.session_state.steps = []
189
-
190
- steps_container = st.container()
191
- answer_container = st.container()
192
- sources_container = st.container()
193
-
194
- with steps_container:
195
- st.subheader("צעדי תהליך החיפוש")
196
-
197
- def handle_step_update(step):
198
- if 'final_result' in step:
199
- final_result = step['final_result']
200
-
201
- with answer_container:
202
- st.subheader("תשובה סופית")
203
- st.info(final_result['answer'])
204
-
205
- if final_result['sources']:
206
- with sources_container:
207
- st.subheader("מסמכי מקור")
208
- st.markdown(f"נמצאו {len(final_result['sources'])} תוצאות")
209
-
210
- for i, source in enumerate(final_result['sources']):
211
- with st.expander(f"תוצאה {i+1}: {source['reference']} (ציון: {source['score']:.2f})"):
212
- st.write(source['text'])
213
-
214
- else:
215
- with steps_container:
216
- step_number = len(st.session_state.steps) + 1
217
- st.markdown(f"""
218
- <div class='search-step'>
219
- <strong>צעד {step_number}. {step['action']}</strong>
220
- </div>
221
- """, unsafe_allow_html=True)
222
- st.markdown(f"**{step['description']}**")
223
-
224
- if 'results' in step:
225
- documents = []
226
-
227
- for r in step['results']:
228
- if r['type'] == 'query':
229
- st.markdown("**שאילתת חיפוש:**")
230
- st.code(r['content'])
231
-
232
- elif r['type'] == 'document':
233
- documents.append(r['content'])
234
-
235
- elif r['type'] == 'evaluation':
236
- content = r['content']
237
- status = "✓" if content['status'] == 'accepted' else "↻"
238
- confidence = f"ביטחון: {content['confidence']}"
239
- if content['status'] == 'accepted':
240
- st.success(f"{status} {confidence}")
241
- else:
242
- st.warning(f"{status} {confidence}")
243
- if content['explanation']:
244
- st.info(content['explanation'])
245
-
246
- elif r['type'] == 'new_query':
247
- st.markdown("**ניסיון הבא:**")
248
- st.code(r['content'])
249
-
250
- # Display documents if any were found
251
- if documents:
252
- for i, doc in enumerate(documents):
253
- with st.expander(f"{doc['reference']} (ציון: {doc['score']:.2f})"):
254
- st.write(doc['highlights'][0])
255
-
256
- st.markdown("---")
257
- st.session_state.steps.append(step)
258
-
259
- # Clear previous steps before starting new search
260
- st.session_state.steps = []
261
-
262
- # Start the search process
263
- self.agent.search_and_answer(
264
- query=query,
265
- num_results=results_per_search,
266
- max_iterations=max_iterations,
267
- on_step=handle_step_update
268
- )
269
-
270
- except Exception as ex:
271
- st.error(f"שגיאת חיפוש: {str(ex)}")
272
-
273
- if __name__ == "__main__":
274
- app = SearchAgentUI()
275
- app.main()
 
1
+ import streamlit as st
2
+ from tantivy_search_agent import TantivySearchAgent
3
+ from agent_workflow import SearchAgent
4
+ import os
5
+ from typing import Optional, List
6
+ from dotenv import load_dotenv
7
+ import gdown
8
+
9
+ # Load environment variables
10
+ load_dotenv()
11
+
12
+ class SearchAgentUI:
13
+ def __init__(self):
14
+ self.tantivy_agent: Optional[TantivySearchAgent] = None
15
+ self.agent: Optional[SearchAgent] = None
16
+ self.index_path ="./index" # os.getenv("INDEX_PATH", "./index")
17
+ # Google Drive folder ID for the index
18
+ self.gdrive_index_id = os.getenv("GDRIVE_INDEX_ID", "1lpbBCPimwcNfC0VZOlQueA4SHNGIp5_t")
19
+ def download_index_from_gdrive(self) -> bool:
20
+ """Download index folder from Google Drive"""
21
+ try:
22
+ # Create a temporary zip file path
23
+ zip_path = "index.zip"
24
+ # Download the folder as a zip file
25
+ url = f"https://drive.google.com/uc?id={self.gdrive_index_id}"
26
+ gdown.download(url, zip_path, quiet=False)
27
+
28
+ # Extract the zip file
29
+ import zipfile
30
+ with zipfile.ZipFile(zip_path, 'r') as zip_ref:
31
+ zip_ref.extractall(".")
32
+
33
+ # Remove the zip file
34
+ os.remove(zip_path)
35
+ return True
36
+ except Exception as e:
37
+ st.error(f"Failed to download index: {str(e)}")
38
+ return False
39
+
40
+ def get_available_providers(self) -> List[str]:
41
+ """Get available providers without creating a SearchAgent instance"""
42
+ temp_tantivy = TantivySearchAgent(self.index_path)
43
+ temp_agent = SearchAgent(temp_tantivy)
44
+ return temp_agent.get_available_providers()
45
+
46
+ def initialize_system(self):
47
+ try:
48
+ # Check if index folder exists
49
+ if not os.path.exists(self.index_path):
50
+ st.warning("Index folder not found. Attempting to download from Google Drive...")
51
+ if not self.download_index_from_gdrive():
52
+ return False, "שגיאה: לא ניתן להוריד את האינדקס", []
53
+ st.success("Index downloaded successfully!")
54
+
55
+ self.tantivy_agent = TantivySearchAgent(self.index_path)
56
+ if self.tantivy_agent.validate_index():
57
+ available_providers = self.get_available_providers()
58
+ self.agent = SearchAgent(
59
+ self.tantivy_agent,
60
+ provider_name=st.session_state.get('provider', available_providers[0])
61
+ )
62
+ return True, "המערכת מוכנה לחיפוש", available_providers
63
+ else:
64
+ return False, "שגיאה: אינדקס לא תקין", []
65
+ except Exception as ex:
66
+ return False, f"שגיאה באתחול המערכת: {str(ex)}", []
67
+
68
+ def main(self):
69
+ st.set_page_config(
70
+ page_title="איתוריא",
71
+ layout="wide",
72
+ initial_sidebar_state="collapsed"
73
+ )
74
+
75
+ # Enhanced RTL support and styling
76
+ st.markdown("""
77
+ <style>
78
+ .stApp {
79
+ direction: rtl;
80
+ }
81
+ .stTextInput > div > div > input {
82
+ direction: rtl;
83
+ }
84
+ .stSelectbox > div > div > div {
85
+ direction: rtl;
86
+ }
87
+ .stNumberInput > div > div > input {
88
+ direction: rtl;
89
+ }
90
+ .search-step {
91
+ border: 1px solid #e0e0e0;
92
+ border-radius: 5px;
93
+ padding: 10px;
94
+ margin: 5px 0;
95
+ background-color: #f8f9fa;
96
+ }
97
+ .document-group {
98
+ border: 1px solid #e3f2fd;
99
+ border-radius: 5px;
100
+ padding: 10px;
101
+ margin: 5px 0;
102
+ background-color: #f5f9ff;
103
+ }
104
+ .document-item {
105
+ border: 1px solid #e0e0e0;
106
+ border-radius: 5px;
107
+ padding: 10px;
108
+ margin: 5px 0;
109
+ background-color: white;
110
+ }
111
+ </style>
112
+ """, unsafe_allow_html=True)
113
+
114
+ # Initialize system
115
+ success, status_msg, available_providers = self.initialize_system()
116
+
117
+ # Header layout
118
+ col1, col2, col3 = st.columns([2,1,1])
119
+
120
+ with col1:
121
+ if success:
122
+ st.success(status_msg)
123
+ else:
124
+ st.error(status_msg)
125
+
126
+ with col2:
127
+ if 'provider' not in st.session_state:
128
+ st.session_state.provider = available_providers[0] if available_providers else None
129
+
130
+ if available_providers:
131
+ provider = st.selectbox(
132
+ "ספק בינה מלאכותית",
133
+ options=available_providers,
134
+ key='provider'
135
+ )
136
+ if self.agent:
137
+ self.agent.set_provider(provider)
138
+
139
+ with col3:
140
+ col3_1, col3_2 = st.columns(2)
141
+ with col3_1:
142
+ max_iterations = st.number_input(
143
+ "מספר נסיונות מקסימלי",
144
+ min_value=1,
145
+ value=3,
146
+ key='max_iterations'
147
+ )
148
+ with col3_2:
149
+ results_per_search = st.number_input(
150
+ "תוצאות לכל חיפוש",
151
+ min_value=1,
152
+ value=5,
153
+ key='results_per_search'
154
+ )
155
+
156
+ # Search input
157
+ query = st.text_input(
158
+ "הכנס שאילתת חיפוש",
159
+ disabled=not success,
160
+ placeholder="הקלד את שאילתת החיפוש שלך כאן...",
161
+ key='search_query'
162
+ )
163
+
164
+ # Search button
165
+ if (st.button('חפש', disabled=not success) or query) and query!="" and self.agent:
166
+ try:
167
+ if 'steps' not in st.session_state:
168
+ st.session_state.steps = []
169
+
170
+ steps_container = st.container()
171
+ answer_container = st.container()
172
+ sources_container = st.container()
173
+
174
+ with steps_container:
175
+ st.subheader("צעדי תהליך החיפוש")
176
+
177
+ def handle_step_update(step):
178
+ if 'final_result' in step:
179
+ final_result = step['final_result']
180
+
181
+ with answer_container:
182
+ st.subheader("תשובה סופית")
183
+ st.info(final_result['answer'])
184
+
185
+ if final_result['sources']:
186
+ with sources_container:
187
+ st.subheader("מסמכי מקור")
188
+ st.markdown(f"נמצאו {len(final_result['sources'])} תוצאות")
189
+
190
+ for i, source in enumerate(final_result['sources']):
191
+ with st.expander(f"תוצאה {i+1}: {source['reference']} (ציון: {source['score']:.2f})"):
192
+ st.write(source['text'])
193
+
194
+ else:
195
+ with steps_container:
196
+ step_number = len(st.session_state.steps) + 1
197
+ st.markdown(f"""
198
+ <div class='search-step'>
199
+ <strong>צעד {step_number}. {step['action']}</strong>
200
+ </div>
201
+ """, unsafe_allow_html=True)
202
+ st.markdown(f"**{step['description']}**")
203
+
204
+ if 'results' in step:
205
+ documents = []
206
+
207
+ for r in step['results']:
208
+ if r['type'] == 'query':
209
+ st.markdown("**שאילתת חיפוש:**")
210
+ st.code(r['content'])
211
+
212
+ elif r['type'] == 'document':
213
+ documents.append(r['content'])
214
+
215
+ elif r['type'] == 'evaluation':
216
+ content = r['content']
217
+ status = "" if content['status'] == 'accepted' else "↻"
218
+ confidence = f"ביטחון: {content['confidence']}"
219
+ if content['status'] == 'accepted':
220
+ st.success(f"{status} {confidence}")
221
+ else:
222
+ st.warning(f"{status} {confidence}")
223
+ if content['explanation']:
224
+ st.info(content['explanation'])
225
+
226
+ elif r['type'] == 'new_query':
227
+ st.markdown("**ניסיון הבא:**")
228
+ st.code(r['content'])
229
+
230
+ # Display documents if any were found
231
+ if documents:
232
+ for i, doc in enumerate(documents):
233
+ with st.expander(f"{doc['reference']} (ציון: {doc['score']:.2f})"):
234
+ st.write(doc['highlights'][0])
235
+
236
+ st.markdown("---")
237
+ st.session_state.steps.append(step)
238
+
239
+ # Clear previous steps before starting new search
240
+ st.session_state.steps = []
241
+
242
+ # Start the search process
243
+ self.agent.search_and_answer(
244
+ query=query,
245
+ num_results=results_per_search,
246
+ max_iterations=max_iterations,
247
+ on_step=handle_step_update
248
+ )
249
+
250
+ except Exception as ex:
251
+ st.error(f"שגיאת חיפוש: {str(ex)}")
252
+
253
+ if __name__ == "__main__":
254
+ app = SearchAgentUI()
255
+ app.main()