Spaces:
Sleeping
Sleeping
Update app.py
Browse filesfix connecting issue with google
app.py
CHANGED
|
@@ -8,9 +8,8 @@ import shutil
|
|
| 8 |
import asyncio
|
| 9 |
|
| 10 |
# ==========================================
|
| 11 |
-
# 0. ASYNC FIX (CRITICAL
|
| 12 |
# ==========================================
|
| 13 |
-
# Fixes "No event loop" errors
|
| 14 |
try:
|
| 15 |
asyncio.get_running_loop()
|
| 16 |
except RuntimeError:
|
|
@@ -23,15 +22,19 @@ st.set_page_config(page_title="Bank Loan Agent", layout="wide")
|
|
| 23 |
warnings.filterwarnings("ignore")
|
| 24 |
|
| 25 |
# ==========================================
|
| 26 |
-
# 2.
|
| 27 |
# ==========================================
|
| 28 |
DB_FILE = "bank.db"
|
| 29 |
INDEX_PATH = "faiss_index"
|
| 30 |
REQUIRED_PDFS = ["Bank Loan Overall Risk Policy.pdf", "Bank Loan Interest Rate Policy.pdf"]
|
| 31 |
|
| 32 |
try:
|
|
|
|
| 33 |
from langchain_groq import ChatGroq
|
| 34 |
from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings
|
|
|
|
|
|
|
|
|
|
| 35 |
from langchain_huggingface import HuggingFaceEmbeddings
|
| 36 |
from langchain_community.vectorstores import FAISS
|
| 37 |
from langchain_community.callbacks import StreamlitCallbackHandler
|
|
@@ -43,7 +46,7 @@ try:
|
|
| 43 |
from langchain_core.tools import tool
|
| 44 |
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
| 45 |
except ImportError as e:
|
| 46 |
-
st.error(f"β
|
| 47 |
st.stop()
|
| 48 |
|
| 49 |
# ==========================================
|
|
@@ -101,32 +104,31 @@ def check_pr_status(user_id: str) -> str:
|
|
| 101 |
return f"PR Status: {row[0]}" if (row and not isinstance(row, str)) else "PR Status: False."
|
| 102 |
|
| 103 |
# ==========================================
|
| 104 |
-
# 5. UI &
|
| 105 |
# ==========================================
|
| 106 |
st.title("π€ Multi-Model Loan Assessor")
|
| 107 |
pdfs_missing = [f for f in REQUIRED_PDFS if not os.path.exists(f)]
|
| 108 |
|
| 109 |
def update_metrics(placeholder):
|
| 110 |
if 'execution_time' in st.session_state:
|
| 111 |
-
ai_time = st.session_state.execution_time
|
| 112 |
col1, col2 = placeholder.columns(2)
|
| 113 |
-
col1.metric("Processing Time", f"{
|
| 114 |
-
col2.metric("
|
| 115 |
|
| 116 |
# --- SIDEBAR ---
|
| 117 |
with st.sidebar:
|
| 118 |
st.header("π Authentication")
|
| 119 |
|
| 120 |
-
# Provider
|
| 121 |
provider_option = st.radio("Select Model:", ["Groq (Llama-3)", "Google (Gemini)"])
|
| 122 |
|
| 123 |
-
# Init
|
| 124 |
if 'auth_status' not in st.session_state:
|
| 125 |
st.session_state['auth_status'] = False
|
| 126 |
st.session_state['api_key'] = None
|
| 127 |
st.session_state['provider'] = None
|
| 128 |
|
| 129 |
-
# Reset on
|
| 130 |
if st.session_state.get('provider') != provider_option:
|
| 131 |
st.session_state['auth_status'] = False
|
| 132 |
st.session_state['api_key'] = None
|
|
@@ -141,30 +143,26 @@ with st.sidebar:
|
|
| 141 |
st.error("β οΈ Enter a key.")
|
| 142 |
else:
|
| 143 |
try:
|
| 144 |
-
with st.spinner(f"
|
| 145 |
-
|
|
|
|
| 146 |
if "Groq" in provider_option:
|
| 147 |
-
|
| 148 |
else:
|
| 149 |
-
#
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
model="gemini-1.5-flash",
|
| 153 |
-
transport="rest" # <--- THIS IS THE FIX
|
| 154 |
-
)
|
| 155 |
-
|
| 156 |
-
# Simple Invoke to test connection
|
| 157 |
-
test_llm.invoke("Hello")
|
| 158 |
|
| 159 |
st.session_state['auth_status'] = True
|
| 160 |
st.session_state['api_key'] = api_key_input
|
| 161 |
-
st.success("β
|
| 162 |
time.sleep(0.5)
|
| 163 |
st.rerun()
|
|
|
|
| 164 |
except Exception as e:
|
| 165 |
st.error(f"β Error: {e}")
|
| 166 |
else:
|
| 167 |
-
st.success(f"β
{st.session_state['provider']}
|
| 168 |
if st.button("π΄ Logout"):
|
| 169 |
st.session_state['auth_status'] = False
|
| 170 |
st.rerun()
|
|
@@ -173,22 +171,19 @@ with st.sidebar:
|
|
| 173 |
if st.button("β»οΈ Rebuild Database"):
|
| 174 |
if os.path.exists(INDEX_PATH): shutil.rmtree(INDEX_PATH)
|
| 175 |
st.cache_resource.clear()
|
| 176 |
-
st.success("Reset Complete.")
|
| 177 |
-
time.sleep(1)
|
| 178 |
st.rerun()
|
| 179 |
|
| 180 |
-
st.divider()
|
| 181 |
if os.path.exists(DB_FILE) and not pdfs_missing:
|
| 182 |
st.success("β
System Ready")
|
| 183 |
else:
|
| 184 |
st.warning(f"β οΈ Missing: {pdfs_missing}")
|
| 185 |
-
|
| 186 |
st.header("Metrics")
|
| 187 |
metrics_placeholder = st.empty()
|
| 188 |
update_metrics(metrics_placeholder)
|
| 189 |
|
| 190 |
# ==========================================
|
| 191 |
-
# 6. MAIN
|
| 192 |
# ==========================================
|
| 193 |
if st.session_state.get('auth_status', False):
|
| 194 |
|
|
@@ -200,7 +195,7 @@ if st.session_state.get('auth_status', False):
|
|
| 200 |
def setup_rag(_provider, _key):
|
| 201 |
if pdfs_missing: st.stop()
|
| 202 |
|
| 203 |
-
#
|
| 204 |
embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
|
| 205 |
|
| 206 |
if os.path.exists(INDEX_PATH):
|
|
@@ -214,18 +209,18 @@ if st.session_state.get('auth_status', False):
|
|
| 214 |
vectorstore.save_local(INDEX_PATH)
|
| 215 |
return vectorstore.as_retriever()
|
| 216 |
|
| 217 |
-
with st.spinner("Loading
|
| 218 |
retriever = setup_rag(current_provider, current_key)
|
| 219 |
|
| 220 |
# --- LLM SETUP ---
|
| 221 |
if "Groq" in current_provider:
|
| 222 |
llm = ChatGroq(api_key=current_key, temperature=0, model_name="llama-3.3-70b-versatile")
|
| 223 |
else:
|
| 224 |
-
#
|
| 225 |
llm = ChatGoogleGenerativeAI(
|
| 226 |
google_api_key=current_key,
|
| 227 |
temperature=0,
|
| 228 |
-
model="gemini-pro",
|
| 229 |
transport="rest"
|
| 230 |
)
|
| 231 |
|
|
@@ -262,7 +257,7 @@ if st.session_state.get('auth_status', False):
|
|
| 262 |
with col2:
|
| 263 |
if btn:
|
| 264 |
query = f"Process Loan {uid}. "
|
| 265 |
-
if use_sim: query += f"SIMULATION: Use Score {sim_score}, Status {sim_status}. Only query Name
|
| 266 |
else: query += "Query SQL for all data."
|
| 267 |
query += " Check Policies. Output Final Report."
|
| 268 |
|
|
@@ -292,4 +287,4 @@ if st.session_state.get('auth_status', False):
|
|
| 292 |
st.text_area("Draft", value=email, height=200)
|
| 293 |
|
| 294 |
elif not st.session_state.get('auth_status', False):
|
| 295 |
-
st.info("π
|
|
|
|
| 8 |
import asyncio
|
| 9 |
|
| 10 |
# ==========================================
|
| 11 |
+
# 0. ASYNC FIX (CRITICAL)
|
| 12 |
# ==========================================
|
|
|
|
| 13 |
try:
|
| 14 |
asyncio.get_running_loop()
|
| 15 |
except RuntimeError:
|
|
|
|
| 22 |
warnings.filterwarnings("ignore")
|
| 23 |
|
| 24 |
# ==========================================
|
| 25 |
+
# 2. IMPORTS & CONSTANTS
|
| 26 |
# ==========================================
|
| 27 |
DB_FILE = "bank.db"
|
| 28 |
INDEX_PATH = "faiss_index"
|
| 29 |
REQUIRED_PDFS = ["Bank Loan Overall Risk Policy.pdf", "Bank Loan Interest Rate Policy.pdf"]
|
| 30 |
|
| 31 |
try:
|
| 32 |
+
# PROVIDERS
|
| 33 |
from langchain_groq import ChatGroq
|
| 34 |
from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings
|
| 35 |
+
import google.generativeai as genai # <--- DIRECT IMPORT FOR VALIDATION
|
| 36 |
+
|
| 37 |
+
# SHARED
|
| 38 |
from langchain_huggingface import HuggingFaceEmbeddings
|
| 39 |
from langchain_community.vectorstores import FAISS
|
| 40 |
from langchain_community.callbacks import StreamlitCallbackHandler
|
|
|
|
| 46 |
from langchain_core.tools import tool
|
| 47 |
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
| 48 |
except ImportError as e:
|
| 49 |
+
st.error(f"β Import Error: {e}")
|
| 50 |
st.stop()
|
| 51 |
|
| 52 |
# ==========================================
|
|
|
|
| 104 |
return f"PR Status: {row[0]}" if (row and not isinstance(row, str)) else "PR Status: False."
|
| 105 |
|
| 106 |
# ==========================================
|
| 107 |
+
# 5. UI & AUTHENTICATION
|
| 108 |
# ==========================================
|
| 109 |
st.title("π€ Multi-Model Loan Assessor")
|
| 110 |
pdfs_missing = [f for f in REQUIRED_PDFS if not os.path.exists(f)]
|
| 111 |
|
| 112 |
def update_metrics(placeholder):
|
| 113 |
if 'execution_time' in st.session_state:
|
|
|
|
| 114 |
col1, col2 = placeholder.columns(2)
|
| 115 |
+
col1.metric("Processing Time", f"{st.session_state.execution_time:.2f}s")
|
| 116 |
+
col2.metric("Status", "Success")
|
| 117 |
|
| 118 |
# --- SIDEBAR ---
|
| 119 |
with st.sidebar:
|
| 120 |
st.header("π Authentication")
|
| 121 |
|
| 122 |
+
# Provider Select
|
| 123 |
provider_option = st.radio("Select Model:", ["Groq (Llama-3)", "Google (Gemini)"])
|
| 124 |
|
| 125 |
+
# State Init
|
| 126 |
if 'auth_status' not in st.session_state:
|
| 127 |
st.session_state['auth_status'] = False
|
| 128 |
st.session_state['api_key'] = None
|
| 129 |
st.session_state['provider'] = None
|
| 130 |
|
| 131 |
+
# Reset on Change
|
| 132 |
if st.session_state.get('provider') != provider_option:
|
| 133 |
st.session_state['auth_status'] = False
|
| 134 |
st.session_state['api_key'] = None
|
|
|
|
| 143 |
st.error("β οΈ Enter a key.")
|
| 144 |
else:
|
| 145 |
try:
|
| 146 |
+
with st.spinner(f"Verifying {provider_option}..."):
|
| 147 |
+
|
| 148 |
+
# --- LIGHTWEIGHT VALIDATION (NO SPINNING) ---
|
| 149 |
if "Groq" in provider_option:
|
| 150 |
+
ChatGroq(api_key=api_key_input).invoke("Hi")
|
| 151 |
else:
|
| 152 |
+
# Use Direct SDK to avoid LangChain/Streamlit Thread Lock
|
| 153 |
+
genai.configure(api_key=api_key_input)
|
| 154 |
+
list(genai.list_models()) # Quick check that doesn't hang
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
|
| 156 |
st.session_state['auth_status'] = True
|
| 157 |
st.session_state['api_key'] = api_key_input
|
| 158 |
+
st.success("β
Valid!")
|
| 159 |
time.sleep(0.5)
|
| 160 |
st.rerun()
|
| 161 |
+
|
| 162 |
except Exception as e:
|
| 163 |
st.error(f"β Error: {e}")
|
| 164 |
else:
|
| 165 |
+
st.success(f"β
{st.session_state['provider']} Active")
|
| 166 |
if st.button("π΄ Logout"):
|
| 167 |
st.session_state['auth_status'] = False
|
| 168 |
st.rerun()
|
|
|
|
| 171 |
if st.button("β»οΈ Rebuild Database"):
|
| 172 |
if os.path.exists(INDEX_PATH): shutil.rmtree(INDEX_PATH)
|
| 173 |
st.cache_resource.clear()
|
|
|
|
|
|
|
| 174 |
st.rerun()
|
| 175 |
|
|
|
|
| 176 |
if os.path.exists(DB_FILE) and not pdfs_missing:
|
| 177 |
st.success("β
System Ready")
|
| 178 |
else:
|
| 179 |
st.warning(f"β οΈ Missing: {pdfs_missing}")
|
| 180 |
+
|
| 181 |
st.header("Metrics")
|
| 182 |
metrics_placeholder = st.empty()
|
| 183 |
update_metrics(metrics_placeholder)
|
| 184 |
|
| 185 |
# ==========================================
|
| 186 |
+
# 6. MAIN LOGIC
|
| 187 |
# ==========================================
|
| 188 |
if st.session_state.get('auth_status', False):
|
| 189 |
|
|
|
|
| 195 |
def setup_rag(_provider, _key):
|
| 196 |
if pdfs_missing: st.stop()
|
| 197 |
|
| 198 |
+
# Always use HuggingFace Embeddings for compatibility
|
| 199 |
embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
|
| 200 |
|
| 201 |
if os.path.exists(INDEX_PATH):
|
|
|
|
| 209 |
vectorstore.save_local(INDEX_PATH)
|
| 210 |
return vectorstore.as_retriever()
|
| 211 |
|
| 212 |
+
with st.spinner("Loading AI..."):
|
| 213 |
retriever = setup_rag(current_provider, current_key)
|
| 214 |
|
| 215 |
# --- LLM SETUP ---
|
| 216 |
if "Groq" in current_provider:
|
| 217 |
llm = ChatGroq(api_key=current_key, temperature=0, model_name="llama-3.3-70b-versatile")
|
| 218 |
else:
|
| 219 |
+
# Use 'gemini-pro' and force 'rest' transport
|
| 220 |
llm = ChatGoogleGenerativeAI(
|
| 221 |
google_api_key=current_key,
|
| 222 |
temperature=0,
|
| 223 |
+
model="gemini-pro",
|
| 224 |
transport="rest"
|
| 225 |
)
|
| 226 |
|
|
|
|
| 257 |
with col2:
|
| 258 |
if btn:
|
| 259 |
query = f"Process Loan {uid}. "
|
| 260 |
+
if use_sim: query += f"SIMULATION: Use Score {sim_score}, Status {sim_status}. Only query Name from DB."
|
| 261 |
else: query += "Query SQL for all data."
|
| 262 |
query += " Check Policies. Output Final Report."
|
| 263 |
|
|
|
|
| 287 |
st.text_area("Draft", value=email, height=200)
|
| 288 |
|
| 289 |
elif not st.session_state.get('auth_status', False):
|
| 290 |
+
st.info("π Select Provider & Validate Key in Sidebar")
|