ahmadsanafarooq commited on
Commit
7f7b708
Β·
verified Β·
1 Parent(s): 351a5f1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -50
app.py CHANGED
@@ -1,17 +1,17 @@
1
  import os
2
  import sqlite3
 
3
  import streamlit as st
4
  from typing import List, TypedDict
 
 
 
 
5
  from langchain_openai import ChatOpenAI
6
  from langchain_community.tools.tavily_search import TavilySearchResults
7
  from langgraph.graph import StateGraph, START, END
8
  from langgraph.checkpoint.sqlite import SqliteSaver
9
 
10
- # --- NEW TOOL IMPORTS ---
11
- import requests # For Slack Webhooks
12
- from sendgrid import SendGridAPIClient
13
- from sendgrid.helpers.mail import Mail
14
-
15
  # --- 1. PAGE SETUP & CUSTOM CSS ---
16
  st.set_page_config(page_title="Strategic Intel-Agent", layout="wide", page_icon="πŸ›‘οΈ")
17
 
@@ -33,40 +33,36 @@ with st.sidebar:
33
  with st.expander("πŸ”‘ API Credentials", expanded=True):
34
  openai_key = st.text_input("OpenAI API Key", value=os.getenv("OPENAI_API_KEY", ""), type="password")
35
  tavily_key = st.text_input("Tavily API Key", value=os.getenv("TAVILY_API_KEY", ""), type="password")
36
- sg_key = st.text_input("SendGrid API Key (Optional)", type="password")
37
- slack_webhook = st.text_input("Slack Webhook URL (Optional)", type="password")
 
 
38
 
39
  thread_id = st.text_input("Session ID", value="global_user_1")
40
 
41
  os.environ["OPENAI_API_KEY"] = openai_key
42
  os.environ["TAVILY_API_KEY"] = tavily_key
43
- os.environ["SENDGRID_API_KEY"] = sg_key
44
 
45
  st.divider()
46
- st.info("The agent will research, allow you to critique the data, and then distribute findings via the tools below.")
47
-
48
- # --- 3. UTILITY TOOLS ---
49
- def send_to_slack(text, webhook_url):
50
- if not webhook_url: return False
51
- payload = {"text": f"πŸš€ *New Market Intel:* \n {text[:500]}..."}
52
- r = requests.post(webhook_url, json=payload)
53
- return r.status_code == 200
54
-
55
- def send_to_email(content, recipient, api_key):
56
- if not api_key or not recipient: return False
57
- message = Mail(
58
- from_email='reports@intel-agent.ai',
59
- to_emails=recipient,
60
- subject='Market Intelligence Report',
61
- plain_text_content=content)
62
  try:
63
- sg = SendGridAPIClient(api_key)
64
- sg.send(message)
 
 
 
65
  return True
66
  except Exception: return False
67
 
68
- # --- 4. AGENT LOGIC (Unchanged as requested) ---
69
- DB_PATH = "/tmp/agent_memory.db"
70
 
71
  class AgentState(TypedDict):
72
  company_name: str
@@ -77,9 +73,13 @@ class AgentState(TypedDict):
77
  @st.cache_resource
78
  def initialize_agent():
79
  llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
80
- search_tool = TavilySearchResults(max_results=3)
81
 
82
  def researcher(state: AgentState):
 
 
 
 
 
83
  iter_count = state.get("iteration", 0)
84
  query = f"Financial SWOT and strategy for {state['company_name']} 2025"
85
  if iter_count > 0:
@@ -112,13 +112,12 @@ config = {"configurable": {"thread_id": thread_id}}
112
 
113
  # --- 6. MAIN GUI ---
114
  st.title("πŸ›‘οΈ Strategic Intel-Agent")
115
- st.caption("v2.0: Agentic Intelligence with Slack & Email Integration")
116
 
117
- # Input Section
118
  with st.container():
119
  col_input, col_btn = st.columns([4, 1])
120
  with col_input:
121
- company = st.text_input("Target Company Name", placeholder="e.g. NVIDIA, Tesla, Microsoft", label_visibility="collapsed")
122
  with col_btn:
123
  if st.button("πŸ” Start Research"):
124
  st.session_state.report_output = None
@@ -131,22 +130,18 @@ current_state = agent_app.get_state(config)
131
 
132
  if current_state.values.get("research_data"):
133
  st.divider()
134
-
135
- # Header with Iteration Metric
136
  m1, m2 = st.columns([3, 1])
137
  with m1:
138
  st.subheader("πŸ“‹ Intelligence Briefing")
139
  with m2:
140
  st.metric("Web Search Cycles", current_state.values.get("iteration", 0))
141
 
142
- # Sources
143
  with st.expander("πŸ“‚ View Raw Research Data", expanded=True):
144
  for item in current_state.values["research_data"]:
145
  st.markdown(f"**Source:** {item['url']}")
146
  st.caption(item['content'])
147
  st.divider()
148
 
149
- # Action Buttons
150
  c1, c2 = st.columns(2)
151
  with c1:
152
  if st.button("βœ… Approve & Generate SWOT", type="primary"):
@@ -161,7 +156,7 @@ if current_state.values.get("research_data"):
161
  agent_app.invoke(None, config)
162
  st.rerun()
163
 
164
- # --- 7. REPORT & TOOL DISTRIBUTION CENTER ---
165
  if st.session_state.report_output:
166
  st.markdown("---")
167
  res_col, tool_col = st.columns([2, 1])
@@ -178,22 +173,11 @@ if st.session_state.report_output:
178
 
179
  with tool_col:
180
  st.markdown("### πŸš€ Distribute Results")
181
-
182
- # Slack Tool
183
- with st.container(border=True):
184
- st.markdown("**Slack Channel**")
185
- if st.button("πŸ“€ Post to Slack"):
186
- if send_to_slack(st.session_state.report_output, slack_webhook):
187
- st.success("Sent to Slack!")
188
- else:
189
- st.error("Slack Webhook missing/invalid")
190
-
191
- # Email Tool
192
  with st.container(border=True):
193
  st.markdown("**Email Delivery**")
194
  email_target = st.text_input("Recipient Email", placeholder="manager@company.com")
195
  if st.button("πŸ“§ Send via Email"):
196
- if send_to_email(st.session_state.report_output, email_target, sg_key):
197
  st.success(f"Email sent to {email_target}")
198
  else:
199
- st.error("Email failed. Check API Key.")
 
1
  import os
2
  import sqlite3
3
+ import smtplib
4
  import streamlit as st
5
  from typing import List, TypedDict
6
+ from email.mime.text import MIMEText
7
+ from email.mime.multipart import MIMEMultipart
8
+
9
+ # LangChain & Graph Imports
10
  from langchain_openai import ChatOpenAI
11
  from langchain_community.tools.tavily_search import TavilySearchResults
12
  from langgraph.graph import StateGraph, START, END
13
  from langgraph.checkpoint.sqlite import SqliteSaver
14
 
 
 
 
 
 
15
  # --- 1. PAGE SETUP & CUSTOM CSS ---
16
  st.set_page_config(page_title="Strategic Intel-Agent", layout="wide", page_icon="πŸ›‘οΈ")
17
 
 
33
  with st.expander("πŸ”‘ API Credentials", expanded=True):
34
  openai_key = st.text_input("OpenAI API Key", value=os.getenv("OPENAI_API_KEY", ""), type="password")
35
  tavily_key = st.text_input("Tavily API Key", value=os.getenv("TAVILY_API_KEY", ""), type="password")
36
+
37
+ with st.expander("πŸ“§ Email Settings (SMTP)", expanded=False):
38
+ sender_email = st.text_input("Your Gmail Address")
39
+ app_password = st.text_input("App Password", type="password", help="Use a Google App Password, not your login password.")
40
 
41
  thread_id = st.text_input("Session ID", value="global_user_1")
42
 
43
  os.environ["OPENAI_API_KEY"] = openai_key
44
  os.environ["TAVILY_API_KEY"] = tavily_key
 
45
 
46
  st.divider()
47
+ st.info("The agent will research, allow you to critique the data, and then distribute findings via email.")
48
+
49
+ # --- 3. UTILITY TOOLS (NEW EMAIL TOOL) ---
50
+ def send_email_smtp(content, recipient, sender, password):
51
+ if not all([content, recipient, sender, password]): return False
52
+ msg = MIMEMultipart()
53
+ msg['From'], msg['To'], msg['Subject'] = sender, recipient, "Market Intelligence Report"
54
+ msg.attach(MIMEText(content, 'plain'))
 
 
 
 
 
 
 
 
55
  try:
56
+ server = smtplib.SMTP('smtp.gmail.com', 587)
57
+ server.starttls()
58
+ server.login(sender, password)
59
+ server.sendmail(sender, recipient, msg.as_string())
60
+ server.quit()
61
  return True
62
  except Exception: return False
63
 
64
+ # --- 4. AGENT LOGIC ---
65
+ DB_PATH = "agent_memory.db"
66
 
67
  class AgentState(TypedDict):
68
  company_name: str
 
73
  @st.cache_resource
74
  def initialize_agent():
75
  llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
 
76
 
77
  def researcher(state: AgentState):
78
+ # Initializing tool inside node to prevent startup validation errors
79
+ if not os.environ.get("TAVILY_API_KEY"):
80
+ return {"research_data": [], "iteration": state.get("iteration", 0) + 1}
81
+
82
+ search_tool = TavilySearchResults(max_results=3)
83
  iter_count = state.get("iteration", 0)
84
  query = f"Financial SWOT and strategy for {state['company_name']} 2025"
85
  if iter_count > 0:
 
112
 
113
  # --- 6. MAIN GUI ---
114
  st.title("πŸ›‘οΈ Strategic Intel-Agent")
115
+ st.caption("v2.1: Agentic Intelligence with SMTP Email Integration")
116
 
 
117
  with st.container():
118
  col_input, col_btn = st.columns([4, 1])
119
  with col_input:
120
+ company = st.text_input("Target Company Name", placeholder="e.g. NVIDIA, Tesla", label_visibility="collapsed")
121
  with col_btn:
122
  if st.button("πŸ” Start Research"):
123
  st.session_state.report_output = None
 
130
 
131
  if current_state.values.get("research_data"):
132
  st.divider()
 
 
133
  m1, m2 = st.columns([3, 1])
134
  with m1:
135
  st.subheader("πŸ“‹ Intelligence Briefing")
136
  with m2:
137
  st.metric("Web Search Cycles", current_state.values.get("iteration", 0))
138
 
 
139
  with st.expander("πŸ“‚ View Raw Research Data", expanded=True):
140
  for item in current_state.values["research_data"]:
141
  st.markdown(f"**Source:** {item['url']}")
142
  st.caption(item['content'])
143
  st.divider()
144
 
 
145
  c1, c2 = st.columns(2)
146
  with c1:
147
  if st.button("βœ… Approve & Generate SWOT", type="primary"):
 
156
  agent_app.invoke(None, config)
157
  st.rerun()
158
 
159
+ # --- 7. REPORT & EMAIL CENTER ---
160
  if st.session_state.report_output:
161
  st.markdown("---")
162
  res_col, tool_col = st.columns([2, 1])
 
173
 
174
  with tool_col:
175
  st.markdown("### πŸš€ Distribute Results")
 
 
 
 
 
 
 
 
 
 
 
176
  with st.container(border=True):
177
  st.markdown("**Email Delivery**")
178
  email_target = st.text_input("Recipient Email", placeholder="manager@company.com")
179
  if st.button("πŸ“§ Send via Email"):
180
+ if send_email_smtp(st.session_state.report_output, email_target, sender_email, app_password):
181
  st.success(f"Email sent to {email_target}")
182
  else:
183
+ st.error("Check SMTP settings & App Password.")