Enhance VayuChat with retry functionality and improved UX
Browse files- Set DeepSeek-R1 as default model with GPT-OSS fallback
- Add retry button for regenerating responses with current model
- Expand question visibility from 20 to all 30 questions organized in categories:
* NCAP Funding & Policy Analysis
* Meteorology & Environmental Factors
* Population & Demographics
* Multi-Pollutant Analysis
* Other Analysis Questions
- Improve chat UI: increase message width from 70% to 85%, fix input width
- Update questions.txt with concrete policy-relevant queries
- Add seaborn to available libraries in system prompt
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- app.py +73 -10
- questions.txt +30 -31
- system_prompt.txt +1 -0
app.py
CHANGED
|
@@ -158,7 +158,7 @@ st.markdown("""
|
|
| 158 |
color: white;
|
| 159 |
padding: 0.75rem 1rem;
|
| 160 |
border-radius: 12px;
|
| 161 |
-
max-width:
|
| 162 |
}
|
| 163 |
|
| 164 |
.user-info {
|
|
@@ -173,7 +173,7 @@ st.markdown("""
|
|
| 173 |
color: #334155;
|
| 174 |
padding: 0.75rem 1rem;
|
| 175 |
border-radius: 12px;
|
| 176 |
-
max-width:
|
| 177 |
}
|
| 178 |
|
| 179 |
.assistant-info {
|
|
@@ -235,6 +235,8 @@ st.markdown("""
|
|
| 235 |
background: #ffffff;
|
| 236 |
padding: 0.75rem 1rem;
|
| 237 |
font-size: 1rem;
|
|
|
|
|
|
|
| 238 |
}
|
| 239 |
|
| 240 |
.stChatInput:focus {
|
|
@@ -563,9 +565,11 @@ if not available_models:
|
|
| 563 |
st.error("No API keys available! Please set up your API keys in the .env file")
|
| 564 |
st.stop()
|
| 565 |
|
| 566 |
-
# Set
|
| 567 |
default_index = 0
|
| 568 |
-
if "
|
|
|
|
|
|
|
| 569 |
default_index = available_models.index("gpt-oss-120b")
|
| 570 |
|
| 571 |
# Simple header - just title and model selector
|
|
@@ -644,12 +648,45 @@ with st.sidebar:
|
|
| 644 |
selected_prompt = None
|
| 645 |
|
| 646 |
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 653 |
|
| 654 |
st.markdown("---")
|
| 655 |
|
|
@@ -815,6 +852,32 @@ for response_id, response in enumerate(st.session_state.responses):
|
|
| 815 |
st.session_state.responses[response_id]["feedback"] = feedback
|
| 816 |
st.success("Thanks for your feedback!")
|
| 817 |
st.rerun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 818 |
|
| 819 |
# Chat input with better guidance
|
| 820 |
prompt = st.chat_input("💬 Ask about air quality trends, compare cities, or request visualizations...", key="main_chat")
|
|
|
|
| 158 |
color: white;
|
| 159 |
padding: 0.75rem 1rem;
|
| 160 |
border-radius: 12px;
|
| 161 |
+
max-width: 85%;
|
| 162 |
}
|
| 163 |
|
| 164 |
.user-info {
|
|
|
|
| 173 |
color: #334155;
|
| 174 |
padding: 0.75rem 1rem;
|
| 175 |
border-radius: 12px;
|
| 176 |
+
max-width: 85%;
|
| 177 |
}
|
| 178 |
|
| 179 |
.assistant-info {
|
|
|
|
| 235 |
background: #ffffff;
|
| 236 |
padding: 0.75rem 1rem;
|
| 237 |
font-size: 1rem;
|
| 238 |
+
width: 100% !important;
|
| 239 |
+
max-width: none !important;
|
| 240 |
}
|
| 241 |
|
| 242 |
.stChatInput:focus {
|
|
|
|
| 565 |
st.error("No API keys available! Please set up your API keys in the .env file")
|
| 566 |
st.stop()
|
| 567 |
|
| 568 |
+
# Set DeepSeek-R1 as default if available
|
| 569 |
default_index = 0
|
| 570 |
+
if "deepseek-R1" in available_models:
|
| 571 |
+
default_index = available_models.index("deepseek-R1")
|
| 572 |
+
elif "gpt-oss-120b" in available_models:
|
| 573 |
default_index = available_models.index("gpt-oss-120b")
|
| 574 |
|
| 575 |
# Simple header - just title and model selector
|
|
|
|
| 648 |
selected_prompt = None
|
| 649 |
|
| 650 |
|
| 651 |
+
# Show all questions but in a scrollable format
|
| 652 |
+
if len(questions) > 0:
|
| 653 |
+
st.markdown("**Select a question to analyze:**")
|
| 654 |
+
# Create expandable sections for better organization
|
| 655 |
+
with st.expander("📊 NCAP Funding & Policy Analysis", expanded=True):
|
| 656 |
+
for i, q in enumerate([q for q in questions if any(word in q.lower() for word in ['ncap', 'funding', 'investment', 'rupee'])]):
|
| 657 |
+
if st.button(q, key=f"ncap_q_{i}", use_container_width=True, help=f"Analyze: {q}"):
|
| 658 |
+
selected_prompt = q
|
| 659 |
+
st.session_state.last_selected_prompt = q
|
| 660 |
+
|
| 661 |
+
with st.expander("🌬️ Meteorology & Environmental Factors", expanded=False):
|
| 662 |
+
for i, q in enumerate([q for q in questions if any(word in q.lower() for word in ['wind', 'temperature', 'humidity', 'rainfall', 'meteorological', 'monsoon', 'barometric'])]):
|
| 663 |
+
if st.button(q, key=f"met_q_{i}", use_container_width=True, help=f"Analyze: {q}"):
|
| 664 |
+
selected_prompt = q
|
| 665 |
+
st.session_state.last_selected_prompt = q
|
| 666 |
+
|
| 667 |
+
with st.expander("👥 Population & Demographics", expanded=False):
|
| 668 |
+
for i, q in enumerate([q for q in questions if any(word in q.lower() for word in ['population', 'capita', 'density', 'exposure'])]):
|
| 669 |
+
if st.button(q, key=f"pop_q_{i}", use_container_width=True, help=f"Analyze: {q}"):
|
| 670 |
+
selected_prompt = q
|
| 671 |
+
st.session_state.last_selected_prompt = q
|
| 672 |
+
|
| 673 |
+
with st.expander("🏭 Multi-Pollutant Analysis", expanded=False):
|
| 674 |
+
for i, q in enumerate([q for q in questions if any(word in q.lower() for word in ['ozone', 'no2', 'correlation', 'multi-pollutant', 'interaction'])]):
|
| 675 |
+
if st.button(q, key=f"multi_q_{i}", use_container_width=True, help=f"Analyze: {q}"):
|
| 676 |
+
selected_prompt = q
|
| 677 |
+
st.session_state.last_selected_prompt = q
|
| 678 |
+
|
| 679 |
+
with st.expander("📈 Other Analysis Questions", expanded=False):
|
| 680 |
+
remaining_questions = [q for q in questions if not any(any(word in q.lower() for word in category) for category in [
|
| 681 |
+
['ncap', 'funding', 'investment', 'rupee'],
|
| 682 |
+
['wind', 'temperature', 'humidity', 'rainfall', 'meteorological', 'monsoon', 'barometric'],
|
| 683 |
+
['population', 'capita', 'density', 'exposure'],
|
| 684 |
+
['ozone', 'no2', 'correlation', 'multi-pollutant', 'interaction']
|
| 685 |
+
])]
|
| 686 |
+
for i, q in enumerate(remaining_questions):
|
| 687 |
+
if st.button(q, key=f"other_q_{i}", use_container_width=True, help=f"Analyze: {q}"):
|
| 688 |
+
selected_prompt = q
|
| 689 |
+
st.session_state.last_selected_prompt = q
|
| 690 |
|
| 691 |
st.markdown("---")
|
| 692 |
|
|
|
|
| 852 |
st.session_state.responses[response_id]["feedback"] = feedback
|
| 853 |
st.success("Thanks for your feedback!")
|
| 854 |
st.rerun()
|
| 855 |
+
|
| 856 |
+
# Add retry button for each assistant response
|
| 857 |
+
col1, col2, col3 = st.columns([1, 1, 2])
|
| 858 |
+
with col1:
|
| 859 |
+
if st.button("🔄 Retry", key=f"retry_{response_id}", help="Regenerate this response with current model"):
|
| 860 |
+
# Get the last user prompt that led to this response
|
| 861 |
+
user_prompt = ""
|
| 862 |
+
if response_id > 0:
|
| 863 |
+
user_prompt = st.session_state.responses[response_id-1].get("content", "")
|
| 864 |
+
|
| 865 |
+
if user_prompt:
|
| 866 |
+
# Remove this response and the user message before it, then re-add the user message
|
| 867 |
+
if response_id > 0:
|
| 868 |
+
# Store the user prompt
|
| 869 |
+
retry_prompt = st.session_state.responses[response_id-1].get("content", "")
|
| 870 |
+
# Remove both user message and assistant response
|
| 871 |
+
del st.session_state.responses[response_id]
|
| 872 |
+
del st.session_state.responses[response_id-1]
|
| 873 |
+
# Re-add user message and trigger new response
|
| 874 |
+
st.session_state.follow_up_prompt = retry_prompt
|
| 875 |
+
st.rerun()
|
| 876 |
+
|
| 877 |
+
with col2:
|
| 878 |
+
if st.button("💬 Follow-up", key=f"followup_{response_id}", help="Ask a follow-up question"):
|
| 879 |
+
st.session_state.follow_up_mode = True
|
| 880 |
+
st.rerun()
|
| 881 |
|
| 882 |
# Chat input with better guidance
|
| 883 |
prompt = st.chat_input("💬 Ask about air quality trends, compare cities, or request visualizations...", key="main_chat")
|
questions.txt
CHANGED
|
@@ -1,31 +1,30 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
Which
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
Compare
|
| 14 |
-
Which
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
Compare
|
| 19 |
-
|
| 20 |
-
Show
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
Show
|
| 30 |
-
|
| 31 |
-
Identify seasonal emergency periods when public health advisories should be issued
|
|
|
|
| 1 |
+
How much NCAP funding did Delhi receive vs its PM2.5 improvement from 2018-2023?
|
| 2 |
+
Which NCAP cities achieved the best PM2.5 reduction per rupee invested?
|
| 3 |
+
Does wind speed above 5 m/s significantly reduce PM2.5 levels in Delhi?
|
| 4 |
+
Show correlation between rainfall and PM2.5 reduction in Mumbai during monsoon
|
| 5 |
+
Which cities with high population have dangerously high PM2.5 exposure levels?
|
| 6 |
+
Compare winter PM2.5 levels: high-funded vs low-funded NCAP cities
|
| 7 |
+
Does temperature increase correlate with ozone levels in Chennai during summer?
|
| 8 |
+
Plot wind direction vs PM2.5 concentration rose diagram for Delhi in November
|
| 9 |
+
Which meteorological factor most influences PM2.5 reduction in Ahmedabad?
|
| 10 |
+
Rank NCAP cities by pollution improvement efficiency per capita funding
|
| 11 |
+
Show monthly PM2.5 trends for top 5 most populated Indian cities
|
| 12 |
+
Does humidity above 70% help reduce PM10 levels in coastal cities?
|
| 13 |
+
Compare NO2 vs PM2.5 correlation in traffic-heavy vs residential areas
|
| 14 |
+
Which NCAP-funded cities still exceed WHO PM2.5 guidelines despite investment?
|
| 15 |
+
Plot seasonal wind patterns vs pollution levels for North Indian cities
|
| 16 |
+
Show population-weighted pollution exposure map across Indian states
|
| 17 |
+
Does solar radiation intensity affect ground-level ozone formation patterns?
|
| 18 |
+
Compare NCAP investment effectiveness: Tier-1 vs Tier-2 cities
|
| 19 |
+
Which high-population cities need emergency NCAP funding based on current PM2.5?
|
| 20 |
+
Show correlation between barometric pressure and pollution accumulation
|
| 21 |
+
Does monsoon season consistently reduce all pollutant levels nationwide?
|
| 22 |
+
Compare multi-pollutant exposure: children vs adults in high-density cities
|
| 23 |
+
Which cities show pollution improvement correlated with NCAP timeline?
|
| 24 |
+
Plot wind speed threshold for effective pollution dispersion by region
|
| 25 |
+
Show relationship between city population density and average PM2.5 exposure
|
| 26 |
+
Compare Ozone-PM2.5-NO2 interaction patterns in Delhi vs Mumbai
|
| 27 |
+
Does vector wind speed predict pollution episodes better than average wind speed?
|
| 28 |
+
Which NCAP phases (1,2,3) showed maximum pollution reduction per investment?
|
| 29 |
+
Show real-time impact: do meteorological alerts help predict pollution spikes?
|
| 30 |
+
Create pollution risk index combining PM2.5, population, and meteorology data
|
|
|
system_prompt.txt
CHANGED
|
@@ -3,6 +3,7 @@ I have a pandas dataframe data of PM2.5 and PM10.
|
|
| 3 |
* Frequency of data is daily.
|
| 4 |
* `pollution` generally means `PM2.5`.
|
| 5 |
* You already have df, so don't read the csv file
|
|
|
|
| 6 |
* Don't print anything, but save result in a variable `answer` and make it global.
|
| 7 |
* Unless explicitly mentioned, don't consider the result as a plot.
|
| 8 |
* PM2.5 guidelines: India: 60, WHO: 15.
|
|
|
|
| 3 |
* Frequency of data is daily.
|
| 4 |
* `pollution` generally means `PM2.5`.
|
| 5 |
* You already have df, so don't read the csv file
|
| 6 |
+
* Available libraries: pandas, matplotlib, numpy, seaborn, plotly, geopandas, statsmodels, scikit-learn
|
| 7 |
* Don't print anything, but save result in a variable `answer` and make it global.
|
| 8 |
* Unless explicitly mentioned, don't consider the result as a plot.
|
| 9 |
* PM2.5 guidelines: India: 60, WHO: 15.
|