galbendavids commited on
Commit
f77d065
·
1 Parent(s): e405ff6

תיקונים: כותרת Agent, ניגודיות סטטוס, ולידציה ג'יבריש, תיקון היסטוריה

Browse files
Files changed (4) hide show
  1. app/api.py +22 -6
  2. app/sql_service.py +40 -2
  3. app/static/app.js +14 -3
  4. app/static/index.html +3 -3
app/api.py CHANGED
@@ -49,13 +49,17 @@ def save_history() -> None:
49
  permissions issue), the error is logged but doesn't break the main flow.
50
  History is stored in `.query_history.json`.
51
  """
 
52
  try:
 
53
  with history_file.open("w", encoding="utf-8") as f:
54
  json.dump(history, f, ensure_ascii=False, indent=2)
55
- print(f"History saved successfully to {history_file}", flush=True)
56
  except Exception as e:
57
  # Log error but don't break main flow
 
58
  print(f"Warning: Could not save history to {history_file}: {e}", flush=True)
 
59
 
60
 
61
  class QueryRequest(BaseModel):
@@ -170,21 +174,25 @@ def query_sql(req: QueryRequest) -> SQLQueryResponse:
170
  })
171
 
172
  # Save to history - ensure it's always saved
 
173
  try:
174
- history.append({
175
  "query": result.user_query,
176
  "response": {"summary": result.summary},
177
  "timestamp": __import__("datetime").datetime.now().isoformat()
178
- })
 
179
  save_history()
180
- print(f"History saved: {len(history)} entries", flush=True)
181
  except Exception as e:
182
  print(f"Error saving history: {e}", flush=True)
 
 
183
  # Try to save anyway, even if there's an error
184
  try:
185
  save_history()
186
- except:
187
- pass
188
 
189
  return SQLQueryResponse(
190
  query=result.user_query,
@@ -233,6 +241,14 @@ def get_history() -> Dict[str, Any]:
233
  Returns all previously asked questions and their responses.
234
  History is persisted to `.query_history.json` and loaded on startup.
235
  """
 
 
 
 
 
 
 
 
236
  return {"history": history}
237
 
238
 
 
49
  permissions issue), the error is logged but doesn't break the main flow.
50
  History is stored in `.query_history.json`.
51
  """
52
+ global history
53
  try:
54
+ # Ensure we're saving the current history
55
  with history_file.open("w", encoding="utf-8") as f:
56
  json.dump(history, f, ensure_ascii=False, indent=2)
57
+ print(f"History saved successfully to {history_file.absolute()}: {len(history)} entries", flush=True)
58
  except Exception as e:
59
  # Log error but don't break main flow
60
+ import traceback
61
  print(f"Warning: Could not save history to {history_file}: {e}", flush=True)
62
+ traceback.print_exc()
63
 
64
 
65
  class QueryRequest(BaseModel):
 
174
  })
175
 
176
  # Save to history - ensure it's always saved
177
+ global history
178
  try:
179
+ history_entry = {
180
  "query": result.user_query,
181
  "response": {"summary": result.summary},
182
  "timestamp": __import__("datetime").datetime.now().isoformat()
183
+ }
184
+ history.append(history_entry)
185
  save_history()
186
+ print(f"History saved: {len(history)} entries. Query: {result.user_query[:50]}...", flush=True)
187
  except Exception as e:
188
  print(f"Error saving history: {e}", flush=True)
189
+ import traceback
190
+ traceback.print_exc()
191
  # Try to save anyway, even if there's an error
192
  try:
193
  save_history()
194
+ except Exception as e2:
195
+ print(f"Second attempt to save history also failed: {e2}", flush=True)
196
 
197
  return SQLQueryResponse(
198
  query=result.user_query,
 
241
  Returns all previously asked questions and their responses.
242
  History is persisted to `.query_history.json` and loaded on startup.
243
  """
244
+ global history
245
+ # Reload history from disk to ensure we have the latest
246
+ if history_file.exists():
247
+ try:
248
+ with history_file.open("r", encoding="utf-8") as f:
249
+ history = json.load(f)
250
+ except Exception:
251
+ pass
252
  return {"history": history}
253
 
254
 
app/sql_service.py CHANGED
@@ -170,8 +170,18 @@ class SQLFeedbackService:
170
  if self.df is None:
171
  raise ValueError("No feedback data available. Please ensure Feedback.csv exists.")
172
 
173
- # Step 1: Generate SQL queries
174
- sql_queries = self._generate_sql_queries(query)
 
 
 
 
 
 
 
 
 
 
175
 
176
  # Step 2: Execute SQL queries
177
  query_results = self._execute_sql_queries(sql_queries)
@@ -190,10 +200,38 @@ class SQLFeedbackService:
190
  visualizations=visualizations
191
  )
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  def _generate_sql_queries(self, query: str) -> List[str]:
194
  """
195
  Use LLM to generate 1-5 SQL queries that will help answer the user's question.
196
  """
 
 
 
 
197
  schema_info = self._get_schema_info()
198
 
199
  prompt = f"""אתה אנליסט נתונים מומחה. המשתמש שאל שאלה על משובי משתמשים.
 
170
  if self.df is None:
171
  raise ValueError("No feedback data available. Please ensure Feedback.csv exists.")
172
 
173
+ # Step 1: Generate SQL queries (with gibberish validation)
174
+ try:
175
+ sql_queries = self._generate_sql_queries(query)
176
+ except ValueError as e:
177
+ # If query is gibberish, return a friendly error message
178
+ return AnalysisResult(
179
+ user_query=query,
180
+ sql_queries=[],
181
+ query_results=[],
182
+ summary=str(e),
183
+ visualizations=None
184
+ )
185
 
186
  # Step 2: Execute SQL queries
187
  query_results = self._execute_sql_queries(sql_queries)
 
200
  visualizations=visualizations
201
  )
202
 
203
+ def _is_gibberish_query(self, query: str) -> bool:
204
+ """
205
+ Check if the query is gibberish or unintelligible.
206
+
207
+ Returns True if the query appears to be gibberish, False otherwise.
208
+ """
209
+ # Remove extra whitespace
210
+ query_clean = query.strip()
211
+
212
+ # Check if query is too short or empty
213
+ if len(query_clean) < 3:
214
+ return True
215
+
216
+ # Check if query contains only special characters or numbers
217
+ if not any(c.isalpha() for c in query_clean):
218
+ return True
219
+
220
+ # Check if query is mostly non-alphabetic characters
221
+ alpha_count = sum(1 for c in query_clean if c.isalpha())
222
+ if alpha_count < len(query_clean) * 0.3: # Less than 30% alphabetic
223
+ return True
224
+
225
+ return False
226
+
227
  def _generate_sql_queries(self, query: str) -> List[str]:
228
  """
229
  Use LLM to generate 1-5 SQL queries that will help answer the user's question.
230
  """
231
+ # Check if query is gibberish
232
+ if self._is_gibberish_query(query):
233
+ raise ValueError("השאלה לא ברורה. אנא נסח את השאלה בצורה יותר ברורה ומפורטת בעברית.")
234
+
235
  schema_info = self._get_schema_info()
236
 
237
  prompt = f"""אתה אנליסט נתונים מומחה. המשתמש שאל שאלה על משובי משתמשים.
app/static/app.js CHANGED
@@ -4,12 +4,23 @@ async function checkServer() {
4
  if (!r.ok) throw new Error('no');
5
  const j = await r.json();
6
  const statusEl = document.getElementById('server-status');
7
- statusEl.textContent = j.status === 'ok' ? '✓ פעיל' : j.status || 'לא ידוע';
8
- statusEl.style.color = j.status === 'ok' ? '#4caf50' : '#f44336';
 
 
 
 
 
 
 
 
 
9
  } catch (e) {
10
  const statusEl = document.getElementById('server-status');
11
  statusEl.textContent = '✗ לא זמין';
12
- statusEl.style.color = '#f44336';
 
 
13
  }
14
  }
15
 
 
4
  if (!r.ok) throw new Error('no');
5
  const j = await r.json();
6
  const statusEl = document.getElementById('server-status');
7
+ if (j.status === 'ok') {
8
+ statusEl.textContent = ' פעיל';
9
+ statusEl.style.color = '#ffffff';
10
+ statusEl.style.textShadow = '0 1px 3px rgba(0,0,0,0.5), 0 0 8px rgba(76, 175, 80, 0.8)';
11
+ statusEl.style.fontWeight = '700';
12
+ } else {
13
+ statusEl.textContent = j.status || 'לא ידוע';
14
+ statusEl.style.color = '#ffebee';
15
+ statusEl.style.textShadow = '0 1px 3px rgba(0,0,0,0.5)';
16
+ statusEl.style.fontWeight = '700';
17
+ }
18
  } catch (e) {
19
  const statusEl = document.getElementById('server-status');
20
  statusEl.textContent = '✗ לא זמין';
21
+ statusEl.style.color = '#ffebee';
22
+ statusEl.style.textShadow = '0 1px 3px rgba(0,0,0,0.5), 0 0 8px rgba(244, 67, 54, 0.8)';
23
+ statusEl.style.fontWeight = '700';
24
  }
25
  }
26
 
app/static/index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Feedback AnalysisFrontend</title>
7
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
8
  <style>
9
  * { box-sizing: border-box; }
@@ -241,9 +241,9 @@
241
  <body>
242
  <div class="container">
243
  <header>
244
- <h1>Feedback Analysis — ממשק</h1>
245
  <div style="display: flex; gap: 16px; align-items: center;">
246
- <div class="small">שרת: <span id="server-status">...בדיקה</span></div>
247
  <a href="https://github.com/galbendavids/Feedback_Analysis_RAG_Agent_runpod" target="_blank" style="color: white; text-decoration: none; font-size: 14px; padding: 6px 12px; background: rgba(255,255,255,0.2); border-radius: 6px; transition: all 0.2s;">🔗 GitHub</a>
248
  <a href="https://github.com/galbendavids/Feedback_Analysis_RAG_Agent_runpod/blob/main/Gal%20Shlomo%20Ben%20David%20Ohayone_e-1.pdf" target="_blank" style="color: white; text-decoration: none; font-size: 14px; padding: 6px 12px; background: rgba(255,255,255,0.2); border-radius: 6px; transition: all 0.2s;">📄 קורות חיים</a>
249
  </div>
 
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Feedback Intelligence Agent ממשק ניתוח משובים</title>
7
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
8
  <style>
9
  * { box-sizing: border-box; }
 
241
  <body>
242
  <div class="container">
243
  <header>
244
+ <h1>🤖 Feedback Intelligence Agent</h1>
245
  <div style="display: flex; gap: 16px; align-items: center;">
246
+ <div class="small" style="background: rgba(255,255,255,0.25); padding: 6px 12px; border-radius: 6px; font-weight: 600;">שרת: <span id="server-status" style="font-weight: 700; text-shadow: 0 1px 2px rgba(0,0,0,0.3);">...בדיקה</span></div>
247
  <a href="https://github.com/galbendavids/Feedback_Analysis_RAG_Agent_runpod" target="_blank" style="color: white; text-decoration: none; font-size: 14px; padding: 6px 12px; background: rgba(255,255,255,0.2); border-radius: 6px; transition: all 0.2s;">🔗 GitHub</a>
248
  <a href="https://github.com/galbendavids/Feedback_Analysis_RAG_Agent_runpod/blob/main/Gal%20Shlomo%20Ben%20David%20Ohayone_e-1.pdf" target="_blank" style="color: white; text-decoration: none; font-size: 14px; padding: 6px 12px; background: rgba(255,255,255,0.2); border-radius: 6px; transition: all 0.2s;">📄 קורות חיים</a>
249
  </div>