Spaces:
Running
Running
| import streamlit as st | |
| from src.retrieval import load_vectorstore, retrieve | |
| from src.hybrid_retrieval import hybrid_retrieve | |
| from src.generation import generate, rewrite_query | |
| from src.language import detect_language | |
| from src.cache import get_cached, set_cached | |
| # โโ Page config โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| st.set_page_config( | |
| page_title="AgroAdvisor BD", | |
| page_icon="๐พ", | |
| layout="wide" | |
| ) | |
| # โโ Load vectorstore once at startup โโโโโโโโโ | |
| def get_vectorstore(): | |
| return load_vectorstore("data/faiss_db") | |
| vectorstore = get_vectorstore() | |
| # โโ Session state init โโโโโโโโโโโโโโโโโโโโโโโโ | |
| if "messages" not in st.session_state: | |
| st.session_state.messages = [] | |
| if "last_sources" not in st.session_state: | |
| st.session_state.last_sources = [] | |
| # โโ Sidebar โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| with st.sidebar: | |
| st.image("https://cdn-icons-png.flaticon.com/512/2889/2889676.png", width=80) | |
| st.title("๐พ AgroAdvisor BD") | |
| st.markdown("Agricultural Disease Advisory for Bangladesh") | |
| st.markdown("---") | |
| try: | |
| chunk_count = vectorstore.count() | |
| st.metric("Knowledge Base", f"{chunk_count:,} chunks") | |
| except Exception: | |
| st.metric("Knowledge Base", "N/A") | |
| st.markdown("**Languages:** ๐ฌ๐ง English | ๐ง๐ฉ เฆฌเฆพเฆเฆฒเฆพ") | |
| st.markdown("**Sources:** BRRI, IRRI, FAO, BARI, USDA, AIS") | |
| st.markdown("---") | |
| if st.button("๐๏ธ Clear Chat"): | |
| st.session_state.messages = [] | |
| st.session_state.last_sources = [] | |
| st.rerun() | |
| if st.session_state.last_sources: | |
| st.markdown("### ๐ Sources Used") | |
| seen = set() | |
| for chunk in st.session_state.last_sources: | |
| if chunk.source not in seen: | |
| seen.add(chunk.source) | |
| display = chunk.source.replace(".pdf", "").replace("_", " ").title() | |
| st.markdown(f"- **{display}** ({chunk.similarity_score:.0%})") | |
| # โโ Main area โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| st.title("๐พ Agricultural Disease Advisory Chatbot") | |
| st.markdown("Ask me anything about crop diseases, symptoms, treatments, and prevention in Bangladesh.") | |
| with st.expander("๐ Example questions to try"): | |
| st.markdown(""" | |
| - What are the symptoms of rice blast disease? | |
| - How do I treat sheath blight in rice? | |
| - What caused the wheat blast outbreak in Bangladesh? | |
| - เฆงเฆพเฆจเงเฆฐ เฆฌเงเฆฒเฆพเฆธเงเฆ เฆฐเงเฆเงเฆฐ เฆฒเฆเงเฆทเฆฃ เฆเง? | |
| - เฆเฆฒเงเฆฐ เฆฒเงเฆ เฆฌเงเฆฒเฆพเฆเฆ เฆฐเงเฆ เฆเงเฆญเฆพเฆฌเง เฆฆเฆฎเฆจ เฆเฆฐเฆฌ? | |
| - How does temperature affect disease spread in rice? | |
| - What fungicide is recommended for rice blast? | |
| - เฆธเฆฐเฆฟเฆทเฆพเฆฐ เฆฐเงเฆ เฆฆเฆฎเฆจเง เฆเง เฆเฆฐเฆฌ? | |
| """) | |
| # โโ Display chat history โโโโโโโโโโโโโโโโโโโโโโโ | |
| for message in st.session_state.messages: | |
| with st.chat_message(message["role"]): | |
| st.markdown(message["content"]) | |
| # โโ Chat input โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| if prompt := st.chat_input("Ask about crop diseases... (English or Bengali)"): | |
| with st.chat_message("user"): | |
| st.markdown(prompt) | |
| st.session_state.messages.append({"role": "user", "content": prompt}) | |
| with st.chat_message("assistant"): | |
| with st.spinner("Searching knowledge base..."): | |
| lang = detect_language(prompt) | |
| history = st.session_state.messages[:-1] | |
| # โโ Check cache first โโโโโโโโโโโโโโโโโโ | |
| cached = get_cached(prompt, lang) | |
| if cached: | |
| answer = cached | |
| used_chunks = [] | |
| chunks = [] | |
| else: | |
| # โโ Rewrite ambiguous queries โโโโโโ | |
| try: | |
| search_query = rewrite_query(prompt, history, lang) | |
| except Exception: | |
| search_query = prompt | |
| # โโ Hybrid retrieval โโโโโโโโโโโโโโโ | |
| try: | |
| chunks, has_reliable = hybrid_retrieve( | |
| search_query, vectorstore, top_k=8 | |
| ) | |
| except Exception: | |
| chunks, has_reliable = retrieve( | |
| search_query, vectorstore, top_k=8 | |
| ) | |
| # โโ Generate answer โโโโโโโโโโโโโโโโ | |
| answer, used_chunks = generate( | |
| query=prompt, | |
| chunks=chunks, | |
| has_reliable=has_reliable, | |
| lang_code=lang, | |
| chat_history=history | |
| ) | |
| # โโ Save to cache โโโโโโโโโโโโโโโโโโ | |
| set_cached(prompt, lang, answer) | |
| st.markdown(answer) | |
| # โโ Show retrieved context โโโโโโโโโโโโโโโโโ | |
| if chunks: | |
| with st.expander("๐ View retrieved context", expanded=False): | |
| for i, chunk in enumerate(chunks): | |
| if chunk.similarity_score >= 0.6: | |
| color = "๐ข" | |
| elif chunk.similarity_score >= 0.35: | |
| color = "๐ก" | |
| else: | |
| color = "๐ด" | |
| st.markdown( | |
| f"{color} **Chunk {i+1}** โ " | |
| f"`{chunk.source}` | Score: `{chunk.similarity_score:.3f}`" | |
| ) | |
| st.text( | |
| chunk.text[:300] + "..." | |
| if len(chunk.text) > 300 | |
| else chunk.text | |
| ) | |
| st.markdown("---") | |
| st.session_state.messages.append({"role": "assistant", "content": answer}) | |
| st.session_state.last_sources = used_chunks | |
| st.rerun() |