Rajan Sharma commited on
Commit
a365d28
·
verified ·
1 Parent(s): 5be3717

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +17 -39
app.py CHANGED
@@ -37,7 +37,6 @@ def _sanitize_text(s: str) -> str:
37
  if not isinstance(s, str): return s
38
  return re2.sub(r'[\p{C}--[\n\t]]+', '', s)
39
 
40
- # THIS FUNCTION IS NOW UPGRADED
41
  def _create_enhanced_prompt(user_scenario: str, file_context: str) -> str:
42
  """Uses an LLM to pre-process the user's prompt and adds critical data context."""
43
  prompt_for_planner = f"""
@@ -100,31 +99,34 @@ def handle(user_msg: str, files: list) -> str:
100
 
101
  if not dataframes: return "Please upload at least one CSV file."
102
 
103
- # Create the crucial file context string
104
  file_context_string = "The user has provided the following data files for your analysis: " + ", ".join(file_names)
105
-
106
  llm = ChatCohere(model=COHERE_MODEL_PRIMARY, temperature=0)
107
  enhanced_prompt = _create_enhanced_prompt(safe_in, file_context_string)
108
 
 
109
  AGENT_PREFIX = """
110
- You are a data analysis agent. You have access to one or more pandas dataframes. Your task is to use the provided dataframes to answer the user's questions.
111
- You MUST respond in one of two formats.
112
 
113
- FORMAT 1: To perform a task.
114
- Thought: Your step-by-step reasoning for using the data.
115
- Action: python_repl_ast
116
- Action Input: The Python code to run on the dataframes (df1, df2, etc.).
 
117
 
118
- FORMAT 2: To give the final answer.
119
- Thought: I have now completed all the tasks and can provide the final report based on the real data.
120
- Final Answer: The complete answer, structured as the user requested.
121
 
122
- CRITICAL RULE: NEVER use hypothetical data. ALWAYS use the provided dataframes to generate your results.
 
123
  """
124
 
125
  agent = create_pandas_dataframe_agent(
126
  llm, dataframes, agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
127
- verbose=True, allow_dangerous_code=True, prefix=AGENT_PREFIX, max_iterations=50
 
 
128
  )
129
  result = agent.invoke({"input": enhanced_prompt})
130
  return _sanitize_text(result.get("output", "No output generated."))
@@ -145,8 +147,6 @@ TERMS_OF_SERVICE_TEXT = load_markdown_text("terms_of_service.md")
145
  with gr.Blocks(theme="soft", css="style.css") as demo:
146
  assessment_history = gr.State([])
147
  # ... (The rest of the UI code is identical to the last version) ...
148
- # ... (For brevity, I will omit it, but you should use the full UI code from the previous step)
149
- # --- MODALS (POPUPS) DEFINED FIRST, INITIALLY HIDDEN ---
150
  with gr.Group(visible=False) as privacy_modal:
151
  with gr.Blocks():
152
  gr.Markdown(PRIVACY_POLICY_TEXT)
@@ -157,11 +157,8 @@ with gr.Blocks(theme="soft", css="style.css") as demo:
157
  gr.Markdown(TERMS_OF_SERVICE_TEXT)
158
  close_terms_btn = gr.Button("Close")
159
 
160
- # --- MAIN UI LAYOUT ---
161
  gr.Markdown("# Universal AI Data Analyst")
162
-
163
  with gr.Row(variant="panel"):
164
- # --- LEFT COLUMN: CONTROLS ---
165
  with gr.Column(scale=1):
166
  gr.Markdown("## New Assessment")
167
  files_input = gr.Files(label="Upload Data Files (.csv)", file_count="multiple", type="filepath", file_types=[".csv"])
@@ -171,28 +168,19 @@ with gr.Blocks(theme="soft", css="style.css") as demo:
171
  clear_btn = gr.Button("🗑️ Clear")
172
  ping_btn = gr.Button("Ping Cohere")
173
  ping_out = gr.Markdown()
174
-
175
- # --- RIGHT COLUMN: RESULTS & HISTORY ---
176
  with gr.Column(scale=2):
177
  with gr.Tabs():
178
  with gr.TabItem("Current Assessment", id=0):
179
- chat_history_output = gr.Chatbot(
180
- label="Analysis Output",
181
- type="messages",
182
- height=600
183
- )
184
  with gr.TabItem("Assessment History", id=1):
185
  gr.Markdown("## Review Past Assessments")
186
  history_dropdown = gr.Dropdown(label="Select an assessment to review", choices=[])
187
  history_display = gr.Markdown(label="Selected Assessment Details")
188
-
189
- # --- FOOTER FOR LEGAL LINKS ---
190
  with gr.Row(): gr.Markdown("---")
191
  with gr.Row():
192
  privacy_link = gr.Button("Privacy Policy", variant="link")
193
  terms_link = gr.Button("Terms of Service", variant="link")
194
 
195
- # --- UI LOGIC ---
196
  def run_analysis_wrapper(prompt, files, chat_history_list, history_state_list):
197
  if not prompt or not files:
198
  gr.Warning("Please provide both a prompt and at least one data file.")
@@ -202,19 +190,13 @@ with gr.Blocks(theme="soft", css="style.css") as demo:
202
  chat_with_user_msg = _append_msg(chat_history_list, "user", prompt)
203
  thinking_message = _append_msg(chat_with_user_msg, "assistant", "```\n🧠 Analyzing... Please wait. This may take a minute.\n```")
204
  yield thinking_message, history_state_list, gr.update()
205
-
206
  ai_response_text = handle(prompt, files)
207
-
208
  final_chat = _append_msg(chat_with_user_msg, "assistant", ai_response_text)
209
-
210
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
211
  file_names = [os.path.basename(f.name if hasattr(f, 'name') else f) for f in files]
212
-
213
  new_assessment = {"id": timestamp, "prompt": prompt, "files": file_names, "response": ai_response_text}
214
  updated_history = history_state_list + [new_assessment]
215
-
216
  history_labels = [f"{item['id']} - {item['prompt'][:40]}..." for item in updated_history]
217
-
218
  yield final_chat, updated_history, gr.update(choices=history_labels)
219
 
220
  def view_history(selection, history_state_list):
@@ -226,7 +208,6 @@ with gr.Blocks(theme="soft", css="style.css") as demo:
226
  return f"""### Assessment from: {selected_assessment['id']}\n**Files Used:**\n- {file_list_md}\n---\n**Original Prompt:**\n> {selected_assessment['prompt']}\n---\n**AI Generated Response:**\n{selected_assessment['response']}"""
227
  return "Could not find the selected assessment."
228
 
229
- # Wire up the components
230
  send_btn.click(
231
  run_analysis_wrapper,
232
  inputs=[prompt_input, files_input, chat_history_output, assessment_history],
@@ -239,14 +220,11 @@ with gr.Blocks(theme="soft", css="style.css") as demo:
239
  )
240
  clear_btn.click(lambda: (None, None, [], []), outputs=[prompt_input, files_input, chat_history_output, assessment_history])
241
  ping_btn.click(ping_cohere, outputs=[ping_out])
242
-
243
- # Wire up the modal popups
244
  privacy_link.click(lambda: gr.update(visible=True), outputs=[privacy_modal])
245
  close_privacy_btn.click(lambda: gr.update(visible=False), outputs=[privacy_modal])
246
  terms_link.click(lambda: gr.update(visible=True), outputs=[terms_modal])
247
  close_terms_btn.click(lambda: gr.update(visible=False), outputs=[terms_modal])
248
 
249
-
250
  if __name__ == "__main__":
251
  if not os.getenv("COHERE_API_KEY"):
252
  print("🔴 COHERE_API_KEY environment variable not set. Application may not function correctly.")
 
37
  if not isinstance(s, str): return s
38
  return re2.sub(r'[\p{C}--[\n\t]]+', '', s)
39
 
 
40
  def _create_enhanced_prompt(user_scenario: str, file_context: str) -> str:
41
  """Uses an LLM to pre-process the user's prompt and adds critical data context."""
42
  prompt_for_planner = f"""
 
99
 
100
  if not dataframes: return "Please upload at least one CSV file."
101
 
 
102
  file_context_string = "The user has provided the following data files for your analysis: " + ", ".join(file_names)
 
103
  llm = ChatCohere(model=COHERE_MODEL_PRIMARY, temperature=0)
104
  enhanced_prompt = _create_enhanced_prompt(safe_in, file_context_string)
105
 
106
+ # --- THE FINAL, STRICTEST AGENT PREFIX ---
107
  AGENT_PREFIX = """
108
+ Your job is to act as a data analyst. You have access to pandas dataframes (df1, df2, etc.).
109
+ You MUST follow these rules. This is not a suggestion.
110
 
111
+ 1. Your response MUST be in one of two formats. NEVER mix them.
112
+ 2. To run code, use this exact format:
113
+ Thought: Your reasoning for the code you are about to run.
114
+ Action: python_repl_ast
115
+ Action Input: The single line of python code to run.
116
 
117
+ 3. To give the final answer, use this exact format:
118
+ Thought: I have finished all the work and have the final answer.
119
+ Final Answer: The complete, final answer to the user's question.
120
 
121
+ NEVER, EVER, provide a "Final Answer" and an "Action" in the same response. This is a fatal error.
122
+ Begin now. Analyze the user's request and provide your first "Thought" and "Action".
123
  """
124
 
125
  agent = create_pandas_dataframe_agent(
126
  llm, dataframes, agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
127
+ verbose=True, allow_dangerous_code=True, prefix=AGENT_PREFIX, max_iterations=50,
128
+ # handle_parsing_errors is now less critical but a good safety net
129
+ handle_parsing_errors=True
130
  )
131
  result = agent.invoke({"input": enhanced_prompt})
132
  return _sanitize_text(result.get("output", "No output generated."))
 
147
  with gr.Blocks(theme="soft", css="style.css") as demo:
148
  assessment_history = gr.State([])
149
  # ... (The rest of the UI code is identical to the last version) ...
 
 
150
  with gr.Group(visible=False) as privacy_modal:
151
  with gr.Blocks():
152
  gr.Markdown(PRIVACY_POLICY_TEXT)
 
157
  gr.Markdown(TERMS_OF_SERVICE_TEXT)
158
  close_terms_btn = gr.Button("Close")
159
 
 
160
  gr.Markdown("# Universal AI Data Analyst")
 
161
  with gr.Row(variant="panel"):
 
162
  with gr.Column(scale=1):
163
  gr.Markdown("## New Assessment")
164
  files_input = gr.Files(label="Upload Data Files (.csv)", file_count="multiple", type="filepath", file_types=[".csv"])
 
168
  clear_btn = gr.Button("🗑️ Clear")
169
  ping_btn = gr.Button("Ping Cohere")
170
  ping_out = gr.Markdown()
 
 
171
  with gr.Column(scale=2):
172
  with gr.Tabs():
173
  with gr.TabItem("Current Assessment", id=0):
174
+ chat_history_output = gr.Chatbot(label="Analysis Output", type="messages", height=600)
 
 
 
 
175
  with gr.TabItem("Assessment History", id=1):
176
  gr.Markdown("## Review Past Assessments")
177
  history_dropdown = gr.Dropdown(label="Select an assessment to review", choices=[])
178
  history_display = gr.Markdown(label="Selected Assessment Details")
 
 
179
  with gr.Row(): gr.Markdown("---")
180
  with gr.Row():
181
  privacy_link = gr.Button("Privacy Policy", variant="link")
182
  terms_link = gr.Button("Terms of Service", variant="link")
183
 
 
184
  def run_analysis_wrapper(prompt, files, chat_history_list, history_state_list):
185
  if not prompt or not files:
186
  gr.Warning("Please provide both a prompt and at least one data file.")
 
190
  chat_with_user_msg = _append_msg(chat_history_list, "user", prompt)
191
  thinking_message = _append_msg(chat_with_user_msg, "assistant", "```\n🧠 Analyzing... Please wait. This may take a minute.\n```")
192
  yield thinking_message, history_state_list, gr.update()
 
193
  ai_response_text = handle(prompt, files)
 
194
  final_chat = _append_msg(chat_with_user_msg, "assistant", ai_response_text)
 
195
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
196
  file_names = [os.path.basename(f.name if hasattr(f, 'name') else f) for f in files]
 
197
  new_assessment = {"id": timestamp, "prompt": prompt, "files": file_names, "response": ai_response_text}
198
  updated_history = history_state_list + [new_assessment]
 
199
  history_labels = [f"{item['id']} - {item['prompt'][:40]}..." for item in updated_history]
 
200
  yield final_chat, updated_history, gr.update(choices=history_labels)
201
 
202
  def view_history(selection, history_state_list):
 
208
  return f"""### Assessment from: {selected_assessment['id']}\n**Files Used:**\n- {file_list_md}\n---\n**Original Prompt:**\n> {selected_assessment['prompt']}\n---\n**AI Generated Response:**\n{selected_assessment['response']}"""
209
  return "Could not find the selected assessment."
210
 
 
211
  send_btn.click(
212
  run_analysis_wrapper,
213
  inputs=[prompt_input, files_input, chat_history_output, assessment_history],
 
220
  )
221
  clear_btn.click(lambda: (None, None, [], []), outputs=[prompt_input, files_input, chat_history_output, assessment_history])
222
  ping_btn.click(ping_cohere, outputs=[ping_out])
 
 
223
  privacy_link.click(lambda: gr.update(visible=True), outputs=[privacy_modal])
224
  close_privacy_btn.click(lambda: gr.update(visible=False), outputs=[privacy_modal])
225
  terms_link.click(lambda: gr.update(visible=True), outputs=[terms_modal])
226
  close_terms_btn.click(lambda: gr.update(visible=False), outputs=[terms_modal])
227
 
 
228
  if __name__ == "__main__":
229
  if not os.getenv("COHERE_API_KEY"):
230
  print("🔴 COHERE_API_KEY environment variable not set. Application may not function correctly.")