Spaces:
Running
Running
Commit ·
cf42361
1
Parent(s): 7a99adf
3.73
Browse files
app.py
CHANGED
|
@@ -559,27 +559,29 @@ class ProcessingUI:
|
|
| 559 |
key="event_filter_key"
|
| 560 |
)
|
| 561 |
|
| 562 |
-
|
| 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 |
-
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
| 578 |
-
</
|
|
|
|
|
|
|
|
|
|
| 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
|
| 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 |
-
|
| 1309 |
-
working_llm = groq_llm if groq_llm is not None else llm
|
| 1310 |
|
| 1311 |
template = """
|
| 1312 |
-
You are a financial analyst
|
| 1313 |
|
| 1314 |
-
|
|
|
|
| 1315 |
|
| 1316 |
-
|
| 1317 |
-
1. "Значительный риск убытков"
|
| 1318 |
-
2. "Умеренный риск убытков"
|
| 1319 |
-
3. "Незначительный риск убытков"
|
| 1320 |
-
4. "Вероятность прибыли"
|
| 1321 |
-
5. "Неопределенный эффект"
|
| 1322 |
|
| 1323 |
-
|
| 1324 |
-
|
| 1325 |
-
|
| 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 |
-
#
|
| 1334 |
-
|
| 1335 |
-
|
| 1336 |
-
|
| 1337 |
-
|
| 1338 |
|
| 1339 |
-
#
|
| 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 |
-
|
| 1344 |
-
|
| 1345 |
-
|
| 1346 |
-
|
| 1347 |
-
|
| 1348 |
-
|
| 1349 |
-
|
| 1350 |
-
|
| 1351 |
-
|
| 1352 |
-
|
| 1353 |
-
|
| 1354 |
-
|
| 1355 |
-
|
| 1356 |
-
|
| 1357 |
-
|
| 1358 |
-
|
| 1359 |
-
|
| 1360 |
-
|
| 1361 |
-
|
| 1362 |
-
|
| 1363 |
-
|
| 1364 |
-
|
| 1365 |
-
|
| 1366 |
-
|
| 1367 |
-
|
| 1368 |
-
|
| 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"
|
| 1375 |
if 'rate limit' in str(e).lower():
|
| 1376 |
-
st.warning("Rate limit reached. Using fallback
|
| 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.
|
| 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(
|