pentarosarium commited on
Commit
cf42361
·
1 Parent(s): 7a99adf
Files changed (1) hide show
  1. app.py +78 -75
app.py CHANGED
@@ -559,27 +559,29 @@ class ProcessingUI:
559
  key="event_filter_key"
560
  )
561
 
562
- # Timeline container
563
- if 'timeline_container' not in st.session_state:
564
- st.session_state.timeline_container = st.container()
565
 
566
  def _update_events_view(self, row, event_type):
567
  """Update events timeline"""
568
  if event_type != 'Нет':
569
  event_html = f"""
570
- <div class='timeline-item'>
571
- <div class='timeline-marker'></div>
572
- <div class='timeline-content'>
573
- <h3>{event_type}</h3>
574
- <p><strong>{row['Объект']}</strong></p>
575
- <p>{row['Заголовок']}</p>
576
- <p>{row['Выдержки из текста']}</p>
577
- <small>{datetime.now().strftime('%H:%M:%S')}</small>
578
- </div>
 
 
 
579
  </div>
580
  """
581
  with self.timeline_container:
582
- st.markdown(event_html, unsafe_allow_html=True)
 
583
  def setup_analytics_tab(self):
584
  """Setup the analytics display"""
585
  # Create containers for analytics
@@ -1296,86 +1298,87 @@ def init_langchain_llm(model_choice):
1296
 
1297
  def estimate_impact(llm, news_text, entity):
1298
  """
1299
- Estimate impact using Groq LLM regardless of the main model choice.
1300
- Falls back to the provided LLM if Groq initialization fails.
1301
  """
1302
- # Initialize default return values
1303
- impact = "Неопределенный эффект"
1304
- reasoning = "Не удалось получить обоснование"
1305
-
1306
  try:
 
 
 
 
 
 
 
 
1307
  # Always try to use Groq first
1308
- groq_llm = ensure_groq_llm()
1309
- working_llm = groq_llm if groq_llm is not None else llm
1310
 
1311
  template = """
1312
- You are a financial analyst. Analyze this news piece about {entity} and assess its potential impact.
1313
 
1314
- News: {news}
 
1315
 
1316
- Classify the impact into one of these categories:
1317
- 1. "Значительный риск убытков" (Significant loss risk)
1318
- 2. "Умеренный риск убытков" (Moderate loss risk)
1319
- 3. "Незначительный риск убытков" (Minor loss risk)
1320
- 4. "Вероятность прибыли" (Potential profit)
1321
- 5. "Неопределенный эффект" (Uncertain effect)
1322
 
1323
- Provide a brief, fact-based reasoning for your assessment.
1324
-
1325
- Format your response exactly as:
1326
- Impact: [category]
1327
- Reasoning: [explanation in 2-3 sentences]
1328
  """
1329
 
1330
  prompt = PromptTemplate(template=template, input_variables=["entity", "news"])
1331
  chain = prompt | working_llm
1332
 
1333
- # Handle both dictionary and direct string inputs
1334
- if isinstance(news_text, dict):
1335
- response = chain.invoke(news_text)
1336
- else:
1337
- response = chain.invoke({"entity": entity, "news": news_text})
1338
 
1339
- # Extract content from response
1340
  response_text = response.content if hasattr(response, 'content') else str(response)
1341
 
 
 
 
 
1342
  if "Impact:" in response_text and "Reasoning:" in response_text:
1343
- try:
1344
- impact_part, reasoning_part = response_text.split("Reasoning:")
1345
- impact_temp = impact_part.split("Impact:")[1].strip()
1346
-
1347
- # Validate impact category
1348
- valid_impacts = [
1349
- "Значительный риск убытков",
1350
- "Умеренный риск убытков",
1351
- "Незначительный риск убытков",
1352
- "Вероятность прибыли",
1353
- "Неопределенный эффект"
1354
- ]
1355
-
1356
- # Use fuzzy matching to handle slight variations
1357
- best_match = None
1358
- best_score = 0
1359
- impact_temp_lower = impact_temp.lower()
1360
-
1361
- for valid_impact in valid_impacts:
1362
- score = fuzz.ratio(impact_temp_lower, valid_impact.lower())
1363
- if score > best_score and score > 80: # 80% similarity threshold
1364
- best_score = score
1365
- best_match = valid_impact
1366
-
1367
- impact = best_match if best_match else "Неопределенный эффект"
1368
- reasoning = reasoning_part.strip()
1369
-
1370
- except Exception as e:
1371
- st.warning(f"Error parsing impact response: {str(e)}")
1372
-
1373
  except Exception as e:
1374
- st.warning(f"Error in impact estimation: {str(e)}")
1375
  if 'rate limit' in str(e).lower():
1376
- st.warning("Rate limit reached. Using fallback model.")
1377
-
1378
- return impact, reasoning
1379
 
1380
  def format_elapsed_time(seconds):
1381
  hours, remainder = divmod(int(seconds), 3600)
@@ -1565,7 +1568,7 @@ def main():
1565
  st.set_page_config(layout="wide")
1566
 
1567
  with st.sidebar:
1568
- st.title("::: AI-анализ мониторинга новостей (v.3.72):::")
1569
  st.subheader("по материалам СКАН-ИНТЕРФАКС")
1570
 
1571
  model_choice = st.radio(
 
559
  key="event_filter_key"
560
  )
561
 
562
+ self.timeline_container = st.container()
 
 
563
 
564
  def _update_events_view(self, row, event_type):
565
  """Update events timeline"""
566
  if event_type != 'Нет':
567
  event_html = f"""
568
+ <div class='timeline-item' style='
569
+ border-left: 4px solid #2196F3;
570
+ margin: 10px 0;
571
+ padding: 10px;
572
+ background: #f5f5f5;
573
+ border-radius: 4px;
574
+ '>
575
+ <h4 style='color: #2196F3; margin: 0;'>{event_type}</h4>
576
+ <p><strong>{row['Объект']}</strong></p>
577
+ <p>{row['Заголовок']}</p>
578
+ <p style='font-size: 0.9em;'>{row['Выдержки из текста']}</p>
579
+ <small style='color: #666;'>{datetime.now().strftime('%H:%M:%S')}</small>
580
  </div>
581
  """
582
  with self.timeline_container:
583
+ st.markdown(event_html, unsafe_allow_html=True)
584
+
585
  def setup_analytics_tab(self):
586
  """Setup the analytics display"""
587
  # Create containers for analytics
 
1298
 
1299
  def estimate_impact(llm, news_text, entity):
1300
  """
1301
+ Estimate impact using Groq LLM with improved error handling and validation.
 
1302
  """
 
 
 
 
1303
  try:
1304
+ # Input validation
1305
+ if not news_text or not entity:
1306
+ return "Неопределенный эффект", "Недостаточно данных для анализа"
1307
+
1308
+ # Clean up inputs
1309
+ news_text = str(news_text).strip()
1310
+ entity = str(entity).strip()
1311
+
1312
  # Always try to use Groq first
1313
+ working_llm = ensure_groq_llm() if 'groq_key' in st.secrets else llm
 
1314
 
1315
  template = """
1316
+ You are a financial analyst tasked with assessing the impact of news on a company.
1317
 
1318
+ Company: {entity}
1319
+ News Text: {news}
1320
 
1321
+ Based on the news content, strictly classify the potential impact into ONE of these categories:
1322
+ 1. "Значительный риск убытков" - For severe negative events like bankruptcy, major legal issues, significant market loss
1323
+ 2. "Умеренный риск убытков" - For moderate negative events like minor legal issues, temporary setbacks
1324
+ 3. "Незначительный риск убытков" - For minor negative events with limited impact
1325
+ 4. "Вероятность прибыли" - For positive events that could lead to profit or growth
1326
+ 5. "Неопределенный эффект" - Only if impact cannot be determined from the information
1327
 
1328
+ FORMAT YOUR RESPONSE EXACTLY AS:
1329
+ Impact: [category name exactly as shown above]
1330
+ Reasoning: [2-3 concise sentences explaining your choice]
 
 
1331
  """
1332
 
1333
  prompt = PromptTemplate(template=template, input_variables=["entity", "news"])
1334
  chain = prompt | working_llm
1335
 
1336
+ # Make the API call
1337
+ response = chain.invoke({
1338
+ "entity": entity,
1339
+ "news": news_text
1340
+ })
1341
 
1342
+ # Parse response
1343
  response_text = response.content if hasattr(response, 'content') else str(response)
1344
 
1345
+ # Extract impact and reasoning
1346
+ impact = "Неопределенный эффект" # Default
1347
+ reasoning = "Не удалось определить влияние" # Default
1348
+
1349
  if "Impact:" in response_text and "Reasoning:" in response_text:
1350
+ parts = response_text.split("Reasoning:")
1351
+ impact_part = parts[0].split("Impact:")[1].strip()
1352
+ reasoning = parts[1].strip()
1353
+
1354
+ # Validate impact category with fuzzy matching
1355
+ valid_impacts = [
1356
+ "Значительный риск убытков",
1357
+ "Умеренный риск убытков",
1358
+ "Незначительный риск убытков",
1359
+ "Вероятность прибыли",
1360
+ "Неопределенный эффект"
1361
+ ]
1362
+
1363
+ # Use fuzzy matching
1364
+ best_match = None
1365
+ best_score = 0
1366
+ for valid_impact in valid_impacts:
1367
+ score = fuzz.ratio(impact_part.lower(), valid_impact.lower())
1368
+ if score > best_score and score > 80: # 80% similarity threshold
1369
+ best_score = score
1370
+ best_match = valid_impact
1371
+
1372
+ if best_match:
1373
+ impact = best_match
1374
+
1375
+ return impact, reasoning
1376
+
 
 
 
1377
  except Exception as e:
1378
+ st.warning(f"Impact estimation error: {str(e)}")
1379
  if 'rate limit' in str(e).lower():
1380
+ st.warning("Rate limit reached. Using fallback analysis.")
1381
+ return "Неопределенный эффект", "Ошибка при анализе влияния"
 
1382
 
1383
  def format_elapsed_time(seconds):
1384
  hours, remainder = divmod(int(seconds), 3600)
 
1568
  st.set_page_config(layout="wide")
1569
 
1570
  with st.sidebar:
1571
+ st.title("::: AI-анализ мониторинга новостей (v.3.73):::")
1572
  st.subheader("по материалам СКАН-ИНТЕРФАКС")
1573
 
1574
  model_choice = st.radio(