pentarosarium commited on
Commit
3cdf7eb
·
1 Parent(s): ab0d1cf
Files changed (1) hide show
  1. app.py +100 -48
app.py CHANGED
@@ -478,7 +478,8 @@ class ProcessingUI:
478
  unsafe_allow_html=True
479
  )
480
  self.progress_bar = st.progress(0)
481
-
 
482
  # Create tabs for different views
483
  tab1, tab2, tab3, tab4 = st.tabs([
484
  "📊 Основные метрики",
@@ -684,7 +685,7 @@ class ProcessingUI:
684
  stats = st.session_state.processing_stats
685
 
686
  # Processing speed chart
687
- speeds = stats['processing_speed'][-50:] # Last 50 measurements
688
  fig_speed = go.Figure(data=go.Scatter(y=speeds, mode='lines'))
689
  fig_speed.update_layout(title='Processing Speed Over Time')
690
  self.speed_chart.plotly_chart(fig_speed, use_container_width=True)
@@ -695,6 +696,7 @@ class ProcessingUI:
695
  """Update progress bar and elapsed time"""
696
  progress = current / total
697
  self.progress_bar.progress(progress)
 
698
 
699
  # Update elapsed time
700
  elapsed = time.time() - st.session_state.processing_stats['start_time']
@@ -969,14 +971,15 @@ def process_file(uploaded_file, model_choice, translation_method=None):
969
 
970
 
971
  # Show events in real-time
972
- if event_type != "Нет":
973
- ui.show_event(
974
- row['Объект'],
975
- event_type,
976
- row['Заголовок']
977
- )
978
 
979
  #Calculate processing speed (items per second)
 
980
  time_delta = current_time - last_update_time
981
  if time_delta > 0:
982
  processing_speed = 1 / time_delta # items per second
@@ -988,29 +991,34 @@ def process_file(uploaded_file, model_choice, translation_method=None):
988
 
989
 
990
  # Handle negative sentiment
 
991
  if sentiment == "Negative":
992
  try:
 
 
 
 
993
  impact, reasoning = estimate_impact(
994
- groq_llm if groq_llm is not None else llm,
995
- translated_text,
996
- row['Объект']
997
  )
 
998
  except Exception as e:
999
  impact = "Неопределенный эффект"
1000
  reasoning = "Error in impact estimation"
1001
- if 'rate limit' in str(e).lower():
1002
- st.warning("Лимит запросов исчерпался. Иду на fallback.")
1003
 
1004
  df.at[idx, 'Impact'] = impact
1005
  df.at[idx, 'Reasoning'] = reasoning
1006
 
1007
  # Show negative alert in real-time
1008
- ui.show_negative(
1009
- row['Объект'],
1010
- row['Заголовок'],
1011
- reasoning,
1012
- impact
1013
- )
1014
 
1015
  processed_rows_df = pd.concat([processed_rows_df, df.iloc[[idx]]], ignore_index=True)
1016
 
@@ -1186,41 +1194,85 @@ def init_langchain_llm(model_choice):
1186
 
1187
 
1188
  def estimate_impact(llm, news_text, entity):
1189
- template = """
1190
- Analyze the following news piece about the entity "{entity}" and estimate its monetary impact in Russian rubles for this entity in the next 6 months.
1191
-
1192
- If precise monetary estimate is not possible, categorize the impact as one of the following:
1193
- 1. "Значительный риск убытков"
1194
- 2. "Умеренный риск убытков"
1195
- 3. "Незначительный риск убытков"
1196
- 4. "Вероятность прибыли"
1197
- 5. "Неопределенный эффект"
1198
-
1199
- Provide brief reasoning (maximum 100 words).
1200
-
1201
- News: {news}
1202
-
1203
- Your response should be in the following format:
1204
- Impact: [Your estimate or category]
1205
- Reasoning: [Your reasoning]
1206
  """
1207
- prompt = PromptTemplate(template=template, input_variables=["entity", "news"])
1208
- chain = prompt | llm
1209
- response = chain.invoke({"entity": entity, "news": news_text})
1210
-
1211
  impact = "Неопределенный эффект"
1212
  reasoning = "Не удалось получить обоснование"
1213
 
1214
- # Extract content from response
1215
- response_text = response.content if hasattr(response, 'content') else str(response)
1216
-
1217
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1218
  if "Impact:" in response_text and "Reasoning:" in response_text:
1219
- impact_part, reasoning_part = response_text.split("Reasoning:")
1220
- impact = impact_part.split("Impact:")[1].strip()
1221
- reasoning = reasoning_part.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1222
  except Exception as e:
1223
- st.error(f"Error parsing LLM response: {str(e)}")
 
 
1224
 
1225
  return impact, reasoning
1226
 
@@ -1412,7 +1464,7 @@ def main():
1412
  st.set_page_config(layout="wide")
1413
 
1414
  with st.sidebar:
1415
- st.title("::: AI-анализ мониторинга новостей (v.3.69!):::")
1416
  st.subheader("по материалам СКАН-ИНТЕРФАКС")
1417
 
1418
  model_choice = st.radio(
 
478
  unsafe_allow_html=True
479
  )
480
  self.progress_bar = st.progress(0)
481
+ self.status = st.empty()
482
+
483
  # Create tabs for different views
484
  tab1, tab2, tab3, tab4 = st.tabs([
485
  "📊 Основные метрики",
 
685
  stats = st.session_state.processing_stats
686
 
687
  # Processing speed chart
688
+ speeds = stats['processing_speed'][-1:] # Last 1 measurement
689
  fig_speed = go.Figure(data=go.Scatter(y=speeds, mode='lines'))
690
  fig_speed.update_layout(title='Processing Speed Over Time')
691
  self.speed_chart.plotly_chart(fig_speed, use_container_width=True)
 
696
  """Update progress bar and elapsed time"""
697
  progress = current / total
698
  self.progress_bar.progress(progress)
699
+ self.status.text(f"Обрабатываем {current} из {total} сообщений...")
700
 
701
  # Update elapsed time
702
  elapsed = time.time() - st.session_state.processing_stats['start_time']
 
971
 
972
 
973
  # Show events in real-time
974
+ #if event_type != "Нет":
975
+ # ui.show_event(
976
+ # row['Объект'],
977
+ # event_type,
978
+ # row['Заголовок']
979
+ # )
980
 
981
  #Calculate processing speed (items per second)
982
+ current_time = time.time()
983
  time_delta = current_time - last_update_time
984
  if time_delta > 0:
985
  processing_speed = 1 / time_delta # items per second
 
991
 
992
 
993
  # Handle negative sentiment
994
+
995
  if sentiment == "Negative":
996
  try:
997
+ # Initialize Groq LLM if not already done
998
+ if 'groq_llm' not in locals():
999
+ groq_llm = ensure_groq_llm()
1000
+
1001
  impact, reasoning = estimate_impact(
1002
+ groq_llm if groq_llm is not None else llm,
1003
+ translated_text,
1004
+ row['Объект']
1005
  )
1006
+
1007
  except Exception as e:
1008
  impact = "Неопределенный эффект"
1009
  reasoning = "Error in impact estimation"
1010
+ st.warning(f"Impact estimation error: {str(e)}")
 
1011
 
1012
  df.at[idx, 'Impact'] = impact
1013
  df.at[idx, 'Reasoning'] = reasoning
1014
 
1015
  # Show negative alert in real-time
1016
+ #ui.show_negative(
1017
+ # row['Объект'],
1018
+ # row['Заголовок'],
1019
+ # reasoning,
1020
+ # impact
1021
+ #)
1022
 
1023
  processed_rows_df = pd.concat([processed_rows_df, df.iloc[[idx]]], ignore_index=True)
1024
 
 
1194
 
1195
 
1196
  def estimate_impact(llm, news_text, entity):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1197
  """
1198
+ Estimate impact using Groq LLM regardless of the main model choice.
1199
+ Falls back to the provided LLM if Groq initialization fails.
1200
+ """
1201
+ # Initialize default return values
1202
  impact = "Неопределенный эффект"
1203
  reasoning = "Не удалось получить обоснование"
1204
 
 
 
 
1205
  try:
1206
+ # Always try to use Groq first
1207
+ groq_llm = ensure_groq_llm()
1208
+ working_llm = groq_llm if groq_llm is not None else llm
1209
+
1210
+ template = """
1211
+ You are a financial analyst. Analyze this news piece about {entity} and assess its potential impact.
1212
+
1213
+ News: {news}
1214
+
1215
+ Classify the impact into one of these categories:
1216
+ 1. "Значительный риск убытков" (Significant loss risk)
1217
+ 2. "Умеренный риск убытков" (Moderate loss risk)
1218
+ 3. "Незначительный риск убытков" (Minor loss risk)
1219
+ 4. "Вероятность прибыли" (Potential profit)
1220
+ 5. "Неопределенный эффект" (Uncertain effect)
1221
+
1222
+ Provide a brief, fact-based reasoning for your assessment.
1223
+
1224
+ Format your response exactly as:
1225
+ Impact: [category]
1226
+ Reasoning: [explanation in 2-3 sentences]
1227
+ """
1228
+
1229
+ prompt = PromptTemplate(template=template, input_variables=["entity", "news"])
1230
+ chain = prompt | working_llm
1231
+
1232
+ # Handle both dictionary and direct string inputs
1233
+ if isinstance(news_text, dict):
1234
+ response = chain.invoke(news_text)
1235
+ else:
1236
+ response = chain.invoke({"entity": entity, "news": news_text})
1237
+
1238
+ # Extract content from response
1239
+ response_text = response.content if hasattr(response, 'content') else str(response)
1240
+
1241
  if "Impact:" in response_text and "Reasoning:" in response_text:
1242
+ try:
1243
+ impact_part, reasoning_part = response_text.split("Reasoning:")
1244
+ impact_temp = impact_part.split("Impact:")[1].strip()
1245
+
1246
+ # Validate impact category
1247
+ valid_impacts = [
1248
+ "Значительный риск убытков",
1249
+ "Умеренный риск убытков",
1250
+ "Незначительный риск убытков",
1251
+ "Вероятность прибыли",
1252
+ "Неопределенный эффект"
1253
+ ]
1254
+
1255
+ # Use fuzzy matching to handle slight variations
1256
+ best_match = None
1257
+ best_score = 0
1258
+ impact_temp_lower = impact_temp.lower()
1259
+
1260
+ for valid_impact in valid_impacts:
1261
+ score = fuzz.ratio(impact_temp_lower, valid_impact.lower())
1262
+ if score > best_score and score > 80: # 80% similarity threshold
1263
+ best_score = score
1264
+ best_match = valid_impact
1265
+
1266
+ impact = best_match if best_match else "Неопределенный эффект"
1267
+ reasoning = reasoning_part.strip()
1268
+
1269
+ except Exception as e:
1270
+ st.warning(f"Error parsing impact response: {str(e)}")
1271
+
1272
  except Exception as e:
1273
+ st.warning(f"Error in impact estimation: {str(e)}")
1274
+ if 'rate limit' in str(e).lower():
1275
+ st.warning("Rate limit reached. Using fallback model.")
1276
 
1277
  return impact, reasoning
1278
 
 
1464
  st.set_page_config(layout="wide")
1465
 
1466
  with st.sidebar:
1467
+ st.title("::: AI-анализ мониторинга новостей (v.3.70):::")
1468
  st.subheader("по материалам СКАН-ИНТЕРФАКС")
1469
 
1470
  model_choice = st.radio(