shoaib4045 commited on
Commit
34f00a2
·
1 Parent(s): b7e1e0c

Enhance conversational AI with context and full Python execution support

Browse files
Files changed (1) hide show
  1. app/main.py +43 -22
app/main.py CHANGED
@@ -697,32 +697,53 @@ async def chat_with_data(job_id: str, req: ChatRequest, _: None = Depends(verify
697
  )
698
 
699
  llm = ChatGroq(model=LLM_MODEL, temperature=0.1, max_tokens=1024)
700
- # Ask LLM to generate a safe pandas expression
 
 
 
701
  schema_info = str(df.dtypes.to_dict())
702
- prompt = f"""You are an expert Data Analyst Agent. You have a pandas DataFrame 'df' loaded with these columns and types: {schema_info}.
703
- The user asks: "{req.query}".
704
- Write a SINGLE line of Python code using pandas that evaluates to a string or number answering this question.
705
- It must be purely an expression (e.g. df['Sales'].mean() or len(df)). No imports, no assignments. Just the expression.
706
- If the question is just greeting/conversational, reply with 'CONVERSATIONAL: ' followed by your response.
707
- Output ONLY the expression or conversational answer."""
 
 
 
 
 
 
 
 
 
 
708
 
709
  try:
710
- ai_expr = llm.invoke([HumanMessage(content=prompt)]).content.strip(" \n`'\"")
711
- if ai_expr.startswith("Python") or ai_expr.startswith("python"):
712
- ai_expr = ai_expr[6:].strip(" \n`")
 
 
713
 
714
- if ai_expr.startswith("CONVERSATIONAL:"):
715
- return {"response": ai_expr.replace("CONVERSATIONAL:", "").strip()}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
716
 
717
- # Safely evaluate
718
- allowed_globals = {"__builtins__": {}, "pd": pd}
719
- allowed_locals = {"df": df}
720
- raw_result = eval(ai_expr, allowed_globals, allowed_locals)
721
-
722
- # Format the result back into english
723
- explanation_prompt = f"The user asked: '{req.query}'. The python result is: {raw_result}. Provide a short, direct human-friendly answer based on this."
724
- final_answer = llm.invoke([HumanMessage(content=explanation_prompt)]).content
725
- return {"response": final_answer}
726
  except Exception as e:
727
  logger.error(f"Chat error: {e}")
728
- return {"response": "I couldn't calculate that from the data right now. Could you rephrase the question?"}
 
697
  )
698
 
699
  llm = ChatGroq(model=LLM_MODEL, temperature=0.1, max_tokens=1024)
700
+
701
+ import numpy as np
702
+
703
+ # Provide better context
704
  schema_info = str(df.dtypes.to_dict())
705
+ sample_data = df.head(3).to_string()
706
+
707
+ prompt = f"""You are an expert Data Analyst Agent. You have a pandas DataFrame 'df' loaded in memory.
708
+ Schema: {schema_info}
709
+ Sample data:
710
+ {sample_data}
711
+
712
+ The user asks: "{req.query}"
713
+
714
+ If the question requires calculating or analyzing the dataframe:
715
+ Write a Python script that assigns the final answer to a variable named `result`.
716
+ You can import libraries if needed (pandas, numpy are already imported as pd, np).
717
+ Enclose your code ONLY in ```python ... ``` block.
718
+
719
+ If the question is conversational or conversational summary of the dataset:
720
+ Just reply directly with text (without any python block!)."""
721
 
722
  try:
723
+ ai_response = llm.invoke([HumanMessage(content=prompt)]).content.strip()
724
+
725
+ # Check if LLM returned code
726
+ if "```python" in ai_response:
727
+ code_block = ai_response.split("```python")[1].split("```")[0].strip()
728
 
729
+ allowed_globals = {"__builtins__": __builtins__, "pd": pd, "np": np}
730
+ allowed_locals = {"df": df}
731
+
732
+ # Execute the code block, expecting it to set 'result' in locals
733
+ exec(code_block, allowed_globals, allowed_locals)
734
+
735
+ if "result" in allowed_locals:
736
+ raw_result = allowed_locals["result"]
737
+ else:
738
+ raw_result = "Code executed successfully but 'result' variable was not set."
739
+
740
+ explanation_prompt = f"The user asked: '{req.query}'. The python result is: {raw_result}. Provide a short, direct human-friendly answer based on this."
741
+ final_answer = llm.invoke([HumanMessage(content=explanation_prompt)]).content
742
+ return {"response": final_answer}
743
+ else:
744
+ # It's purely conversational
745
+ return {"response": ai_response}
746
 
 
 
 
 
 
 
 
 
 
747
  except Exception as e:
748
  logger.error(f"Chat error: {e}")
749
+ return {"response": f"I tried to analyze your data but encountered an error: {str(e)}"}