Aarya003 commited on
Commit
0deb3bf
ยท
verified ยท
1 Parent(s): 22055b7

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +49 -39
src/streamlit_app.py CHANGED
@@ -28,6 +28,7 @@ st.markdown("""
28
  border-radius: 5px;
29
  height: 3em;
30
  background-color: #f0f2f6;
 
31
  }
32
  .reportview-container {
33
  background: #ffffff;
@@ -35,22 +36,34 @@ st.markdown("""
35
  </style>
36
  """, unsafe_allow_html=True)
37
 
38
- # Ensure keys exist
39
  if "OPENAI_API_KEY" not in os.environ:
40
  st.error("โŒ OPENAI_API_KEY missing. Please check Space Settings.")
41
  st.stop()
42
 
43
- # --- 2. DATA MODELS ---
44
  class AgentResponse(BaseModel):
 
 
 
 
 
45
  answer: str
46
  sources: List[str]
47
  context_used: List[str]
48
 
49
  class TickerExtraction(BaseModel):
50
- symbols: List[str] = Field(description="List of stock tickers.")
 
 
 
 
51
 
52
  class RoutePrediction(BaseModel):
53
- tools: List[Literal["financial_rag", "market_data", "general_chat"]] = Field(description="Tools list")
 
 
 
 
54
 
55
  # --- 3. CACHED INITIALIZATION ---
56
  @st.cache_resource(show_spinner=False)
@@ -86,6 +99,9 @@ def initialize_resources():
86
 
87
  return nasdaq_df, index
88
 
 
 
 
89
  # --- 4. HELPER FUNCTIONS ---
90
  def get_symbol_from_csv(query_str: str, df) -> Optional[str]:
91
  if df.empty: return None
@@ -206,31 +222,15 @@ def run_agent(user_query: str, index, df) -> AgentResponse:
206
  # --- 7. UI LOGIC ---
207
  with st.sidebar:
208
  st.image("https://img.icons8.com/color/96/000000/bullish.png", width=80)
209
- st.title("System Status")
210
 
211
- with st.spinner("Connecting to Wall St..."):
212
- nasdaq_df, pinecone_index = initialize_resources()
213
-
214
- if not nasdaq_df.empty:
215
- st.success(f"โœ… Market Data: {len(nasdaq_df):,} Tickers")
216
- else:
217
- st.warning("โš ๏ธ Market Data: Offline")
218
-
219
- if pinecone_index:
220
- st.success("โœ… Knowledge Base: Online")
221
- else:
222
- st.error("โŒ Knowledge Base: Offline")
223
-
224
- st.markdown("---")
225
- st.markdown("### ๐Ÿง  Capabilities")
226
 
227
  st.info("**Deep Dive (10-K Reports)**")
228
- st.markdown("- ๐ŸŽ Apple (AAPL)\n- ๐Ÿš— Tesla (TSLA)\n- ๐ŸŽฎ Nvidia (NVDA)")
229
- st.caption("*Ask about Strategy, Risks, Revenue*")
230
 
231
- st.info("**Live Market Data**")
232
- st.markdown("- ๐ŸŒ All NASDAQ Companies")
233
- st.caption("*Ask about Price, PE Ratio, Volume*")
234
 
235
  st.markdown("---")
236
  if st.button("๐Ÿงน Clear Conversation"):
@@ -240,19 +240,30 @@ with st.sidebar:
240
  # Main Hero Section
241
  st.title("๐Ÿ›๏ธ Wall St. AI Analyst")
242
  st.markdown("""
243
- **Your Hybrid Financial Assistant.** I bridge the gap between **Real-Time Market Data** and **Deep 10-K Analysis**.
 
244
  """)
245
 
246
- # Quick Start Buttons
247
- col1, col2, col3 = st.columns(3)
248
- if col1.button("๐Ÿ†š Compare Risks"):
249
- prompt = "Compare the supply chain risks of Apple and Tesla."
250
- elif col2.button("๐Ÿ“Š Apple vs Nvidia Revenue"):
251
- prompt = "Compare the revenue growth of Apple and Nvidia."
252
- elif col3.button("๐Ÿ“ˆ Tesla PE & Price"):
253
- prompt = "What is the current price and PE ratio of Tesla?"
254
- else:
255
- prompt = None
 
 
 
 
 
 
 
 
 
 
256
 
257
  # Chat State
258
  if "messages" not in st.session_state:
@@ -272,7 +283,6 @@ for message in st.session_state.messages:
272
 
273
  # Handle Input (Button or Text)
274
  if user_input := st.chat_input("Ask a financial question...") or prompt:
275
- # If button was clicked, override text input
276
  final_query = prompt if prompt else user_input
277
 
278
  st.session_state.messages.append({"role": "user", "content": final_query})
@@ -280,7 +290,7 @@ if user_input := st.chat_input("Ask a financial question...") or prompt:
280
  st.markdown(final_query)
281
 
282
  with st.chat_message("assistant"):
283
- # Status container (collapsible)
284
  with st.status("๐Ÿง  Analyzing 10-Ks and Market Data...", expanded=True) as status:
285
  try:
286
  response = run_agent(final_query, pinecone_index, nasdaq_df)
@@ -290,7 +300,7 @@ if user_input := st.chat_input("Ask a financial question...") or prompt:
290
  status.update(label="โŒ Error", state="error")
291
  st.stop()
292
 
293
- # ANSWER DISPLAY (Now OUTSIDE the status block so it auto-shows)
294
  st.markdown(response.answer)
295
 
296
  # Sources (Collapsible)
 
28
  border-radius: 5px;
29
  height: 3em;
30
  background-color: #f0f2f6;
31
+ border: 1px solid #d1d5db;
32
  }
33
  .reportview-container {
34
  background: #ffffff;
 
36
  </style>
37
  """, unsafe_allow_html=True)
38
 
 
39
  if "OPENAI_API_KEY" not in os.environ:
40
  st.error("โŒ OPENAI_API_KEY missing. Please check Space Settings.")
41
  st.stop()
42
 
43
+ # --- 2. DATA MODELS (WITH REQUIRED DOCSTRINGS) ---
44
  class AgentResponse(BaseModel):
45
+ """
46
+ Structured output for the financial agent.
47
+ Contains the synthesized natural language answer, the list of cited sources,
48
+ and the raw context chunks used to formulate the answer.
49
+ """
50
  answer: str
51
  sources: List[str]
52
  context_used: List[str]
53
 
54
  class TickerExtraction(BaseModel):
55
+ """
56
+ Extracts a list of stock tickers or company names mentioned in the user's query.
57
+ Used to identify which companies the user wants to research.
58
+ """
59
+ symbols: List[str] = Field(description="List of stock tickers or company names.")
60
 
61
  class RoutePrediction(BaseModel):
62
+ """
63
+ Determines which tools to use based on the user's query.
64
+ Can select multiple tools if the query requires both financial RAG and market data.
65
+ """
66
+ tools: List[Literal["financial_rag", "market_data", "general_chat"]] = Field(description="List of selected tools.")
67
 
68
  # --- 3. CACHED INITIALIZATION ---
69
  @st.cache_resource(show_spinner=False)
 
99
 
100
  return nasdaq_df, index
101
 
102
+ # Silently load resources
103
+ nasdaq_df, pinecone_index = initialize_resources()
104
+
105
  # --- 4. HELPER FUNCTIONS ---
106
  def get_symbol_from_csv(query_str: str, df) -> Optional[str]:
107
  if df.empty: return None
 
222
  # --- 7. UI LOGIC ---
223
  with st.sidebar:
224
  st.image("https://img.icons8.com/color/96/000000/bullish.png", width=80)
 
225
 
226
+ st.markdown("### ๐Ÿง  Agent Capabilities")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
  st.info("**Deep Dive (10-K Reports)**")
229
+ st.markdown("I have ingested the full SEC 10-K filings for the following companies:")
230
+ st.markdown("- ๐ŸŽ **Apple (AAPL)**\n- ๐Ÿš— **Tesla (TSLA)**\n- ๐ŸŽฎ **Nvidia (NVDA)**")
231
 
232
+ st.success("**Live Market Data**")
233
+ st.markdown("I can fetch real-time trading metrics for **all companies listed on the NASDAQ**.")
 
234
 
235
  st.markdown("---")
236
  if st.button("๐Ÿงน Clear Conversation"):
 
240
  # Main Hero Section
241
  st.title("๐Ÿ›๏ธ Wall St. AI Analyst")
242
  st.markdown("""
243
+ Welcome! This hybrid AI agent bridges the gap between **Real-Time Market Data** and **Deep 10-K Analysis**.
244
+ It utilizes a dynamic routing engine to fetch real-time quantitative metrics via `yfinance` and qualitative insights from a Pinecone Vector Database.
245
  """)
246
 
247
+ # Sample Questions Section
248
+ with st.expander("๐Ÿ’ก View Sample Questions", expanded=True):
249
+ st.markdown("""
250
+ **Try asking about Qualitative 10-K Data:**
251
+ * *"What are the primary supply chain risks mentioned in Apple's latest 10-K?"*
252
+ * *"Who is the CEO of Nvidia and what is their strategy?"*
253
+
254
+ **Try asking for Real-Time Quantitative Data:**
255
+ * *"What is the current PE ratio and market cap of Tesla?"*
256
+ * *"Fetch the trading volume and 52-week high for Microsoft."*
257
+
258
+ **Try a Hybrid Search (Live Data + RAG):**
259
+ * *"Compare the competitive threats facing Tesla with its current stock price."*
260
+ """)
261
+
262
+ # Single Automated Action Button
263
+ if st.button("๐Ÿš€ Auto-Run a Complex Query: Compare Apple & Tesla Risks"):
264
+ prompt = "Compare the supply chain risks of Apple and Tesla."
265
+ else:
266
+ prompt = None
267
 
268
  # Chat State
269
  if "messages" not in st.session_state:
 
283
 
284
  # Handle Input (Button or Text)
285
  if user_input := st.chat_input("Ask a financial question...") or prompt:
 
286
  final_query = prompt if prompt else user_input
287
 
288
  st.session_state.messages.append({"role": "user", "content": final_query})
 
290
  st.markdown(final_query)
291
 
292
  with st.chat_message("assistant"):
293
+ # The spinner happens here
294
  with st.status("๐Ÿง  Analyzing 10-Ks and Market Data...", expanded=True) as status:
295
  try:
296
  response = run_agent(final_query, pinecone_index, nasdaq_df)
 
300
  status.update(label="โŒ Error", state="error")
301
  st.stop()
302
 
303
+ # The answer prints outside the status block so it is immediately visible!
304
  st.markdown(response.answer)
305
 
306
  # Sources (Collapsible)