sanjaystarc commited on
Commit
78d0a49
·
verified ·
1 Parent(s): 3a5adc2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -22
app.py CHANGED
@@ -4,7 +4,7 @@ import pandas as pd
4
  import matplotlib.pyplot as plt
5
  import seaborn as sns
6
 
7
- # Using stable, modern imports to avoid version conflicts
8
  from langchain_google_genai import ChatGoogleGenerativeAI
9
  from langchain_experimental.agents.agent_toolkits import create_pandas_dataframe_agent
10
  from langchain_community.callbacks.streamlit import StreamlitCallbackHandler
@@ -22,20 +22,18 @@ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
22
  def main():
23
  st.title("🤖 Agentic Data Analyst")
24
  st.markdown("""
25
- This agent follows an **agentic workflow**: it reasons about your question, writes Python code,
26
- observes the output, and self-corrects if it encounters errors.
27
  """)
28
 
29
- # Check for API Key
30
  if not GEMINI_API_KEY:
31
- st.error("❌ Missing `GEMINI_API_KEY`. Please set it as an environment variable or in Streamlit Secrets.")
32
  st.stop()
33
 
34
  # --- 2. DATA LOADING ---
35
  uploaded_file = st.file_uploader("Upload your CSV file", type="csv")
36
 
37
  if uploaded_file:
38
- # Load and cache for performance
39
  @st.cache_data
40
  def load_data(file):
41
  return pd.read_csv(file)
@@ -47,37 +45,47 @@ def main():
47
  st.info(f"Dataset contains {df.shape[0]} rows and {df.shape[1]} columns.")
48
 
49
  # --- 3. AGENT CONFIGURATION ---
50
- query = st.text_area("What analysis would you like to perform?", placeholder="e.g., 'Analyze the relationship between x and y and show a scatter plot.'")
51
 
52
  if st.button("Run Agent") and query:
53
- # Initialize the LLM (using Gemini 2.5 Flash for speed/reasoning balance)
54
  llm = ChatGoogleGenerativeAI(
55
- model="gemini-2.5-flash-preview-09-2025",
56
  google_api_key=GEMINI_API_KEY,
57
- temperature=0, # Crucial for deterministic data analysis
58
  )
59
 
60
- # Create the Pandas Agent
61
- # Using the string identifier 'zero-shot-react-description' avoids import errors
 
 
 
 
 
 
 
62
  agent = create_pandas_dataframe_agent(
63
  llm,
64
  df,
65
  verbose=True,
66
  agent_type="zero-shot-react-description",
67
- allow_dangerous_code=True, # Required to execute Python on the dataframe
68
- handle_parsing_errors=True
 
 
 
 
 
 
69
  )
70
 
71
- # --- 4. EXECUTION WITH VISUAL CALLBACKS ---
72
  st.subheader("🧠 Reasoning & Execution")
73
-
74
- # This container allows the user to see the agent's step-by-step thinking
75
  thought_container = st.container()
76
  st_callback = StreamlitCallbackHandler(thought_container)
77
 
78
- with st.spinner("Agent is working..."):
79
  try:
80
- # Execute the loop
81
  response = agent.run(query, callbacks=[st_callback])
82
 
83
  st.markdown("---")
@@ -85,10 +93,12 @@ def main():
85
  st.success(response)
86
 
87
  except Exception as e:
88
- st.error(f"Agent failed to complete the task: {e}")
89
- st.info("Try rephrasing your query or checking if the column names are easy for the AI to understand.")
 
 
90
  else:
91
- st.info("👆 Upload a CSV to begin the agentic session.")
92
 
93
  if __name__ == "__main__":
94
  main()
 
4
  import matplotlib.pyplot as plt
5
  import seaborn as sns
6
 
7
+ # Updated LangChain Imports
8
  from langchain_google_genai import ChatGoogleGenerativeAI
9
  from langchain_experimental.agents.agent_toolkits import create_pandas_dataframe_agent
10
  from langchain_community.callbacks.streamlit import StreamlitCallbackHandler
 
22
  def main():
23
  st.title("🤖 Agentic Data Analyst")
24
  st.markdown("""
25
+ This agent follows an **agentic workflow**: it reasons, writes code,
26
+ observes results, and self-corrects.
27
  """)
28
 
 
29
  if not GEMINI_API_KEY:
30
+ st.error("❌ Missing `GEMINI_API_KEY`. Please set it as an environment variable.")
31
  st.stop()
32
 
33
  # --- 2. DATA LOADING ---
34
  uploaded_file = st.file_uploader("Upload your CSV file", type="csv")
35
 
36
  if uploaded_file:
 
37
  @st.cache_data
38
  def load_data(file):
39
  return pd.read_csv(file)
 
45
  st.info(f"Dataset contains {df.shape[0]} rows and {df.shape[1]} columns.")
46
 
47
  # --- 3. AGENT CONFIGURATION ---
48
+ query = st.text_area("What analysis would you like to perform?", placeholder="e.g., 'Plot the distribution of prices.'")
49
 
50
  if st.button("Run Agent") and query:
 
51
  llm = ChatGoogleGenerativeAI(
52
+ model="gemini-2.5-flash",
53
  google_api_key=GEMINI_API_KEY,
54
+ temperature=0,
55
  )
56
 
57
+ # CUSTOM PROMPT PREFIX: Helps Gemini follow the ReAct format strictly to avoid parsing errors
58
+ custom_prefix = """
59
+ You are working with a pandas dataframe in Python. The name of the dataframe is `df`.
60
+ You should use the tools below to answer the question posed of you.
61
+ IMPORTANT: Your 'Action Input' must be valid Python code and ONLY Python code.
62
+ Do not wrap the code in markdown code blocks within the Action Input.
63
+ """
64
+
65
+ # Create the Pandas Agent with enhanced error handling
66
  agent = create_pandas_dataframe_agent(
67
  llm,
68
  df,
69
  verbose=True,
70
  agent_type="zero-shot-react-description",
71
+ allow_dangerous_code=True,
72
+ prefix=custom_prefix,
73
+ # Pass handle_parsing_errors here AND in agent_executor_kwargs for maximum stability
74
+ handle_parsing_errors=True,
75
+ agent_executor_kwargs={
76
+ "handle_parsing_errors": True,
77
+ "max_iterations": 5
78
+ }
79
  )
80
 
81
+ # --- 4. EXECUTION ---
82
  st.subheader("🧠 Reasoning & Execution")
 
 
83
  thought_container = st.container()
84
  st_callback = StreamlitCallbackHandler(thought_container)
85
 
86
+ with st.spinner("Agent is analyzing..."):
87
  try:
88
+ # Run the loop
89
  response = agent.run(query, callbacks=[st_callback])
90
 
91
  st.markdown("---")
 
93
  st.success(response)
94
 
95
  except Exception as e:
96
+ st.error(f"Agent failed to complete the task.")
97
+ with st.expander("Show Technical Error"):
98
+ st.code(str(e))
99
+ st.info("💡 Tip: The agent had trouble formatting its 'Action'. Try asking the question again or rephrasing it.")
100
  else:
101
+ st.info("👆 Upload a CSV to begin.")
102
 
103
  if __name__ == "__main__":
104
  main()