Soumik555 commited on
Commit
f8d95b7
·
1 Parent(s): f46e49b

added together ai agent

Browse files
controller.py CHANGED
@@ -367,7 +367,7 @@ async def csv_chat(request: Dict, authorization: str = Header(None)):
367
  # groq_answer = await asyncio.to_thread(groq_chat, decoded_url, query)
368
  # logger.info("groq_answer:", groq_answer)
369
 
370
- result = await query_csv_agent(decoded_url, query)
371
  logger.info("together ai csv answer == >", result)
372
  return {"answer": result}
373
 
@@ -633,7 +633,7 @@ async def csv_chart(request: dict, authorization: str = Header(None)):
633
  # return {"image_url": image_public_url}
634
  # return FileResponse(groq_result, media_type="image/png")
635
 
636
- result = await query_csv_agent(csv_url,query)
637
  logger.info("together ai result ==>", result)
638
  return {"orchestrator_response": jsonable_encoder(result)}
639
 
 
367
  # groq_answer = await asyncio.to_thread(groq_chat, decoded_url, query)
368
  # logger.info("groq_answer:", groq_answer)
369
 
370
+ result = await query_csv_agent(decoded_url, query, chat_id)
371
  logger.info("together ai csv answer == >", result)
372
  return {"answer": result}
373
 
 
633
  # return {"image_url": image_public_url}
634
  # return FileResponse(groq_result, media_type="image/png")
635
 
636
+ result = await query_csv_agent(csv_url, query, chat_id)
637
  logger.info("together ai result ==>", result)
638
  return {"orchestrator_response": jsonable_encoder(result)}
639
 
python_code_executor_service.py CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  import uuid
2
  import matplotlib.pyplot as plt
3
  from pathlib import Path
@@ -14,6 +17,10 @@ import seaborn as sns
14
  import scipy.stats as stats
15
  from pydantic import BaseModel
16
 
 
 
 
 
17
 
18
  class CodeResponse(BaseModel):
19
  """Container for code-related responses"""
@@ -136,126 +143,107 @@ class PythonExecutor:
136
  'plots': plots
137
  }
138
 
139
- def save_plot_dummy(self, plot_data: bytes, description: str) -> str:
140
  """
141
- Save plot to charts folder and return a dummy URL
142
 
143
  Args:
144
  plot_data (bytes): Image data in bytes
145
  description (str): Description of the plot
 
146
 
147
  Returns:
148
- str: Dummy URL for the chart
149
  """
150
  # Generate unique filename
151
  filename = f"chart_{uuid.uuid4().hex}.png"
152
  filepath = self.charts_folder / filename
153
 
154
- # Save the plot (even though we're using dummy URLs, we still save it)
155
  with open(filepath, 'wb') as f:
156
  f.write(plot_data)
157
 
158
- # Return a dummy URL
159
- return f"https://example.com/charts/{filename}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
- # def process_response(self, response: CsvChatResult) -> str:
162
- # """
163
- # Process the CsvChatResult response and generate formatted output
 
164
 
165
- # Args:
166
- # response (CsvChatResult): Response from CSV analysis
 
167
 
168
- # Returns:
169
- # str: Formatted output with results and dummy image URLs
170
- # """
171
- # output_parts = []
172
 
173
- # # Add casual response
174
- # output_parts.append(response.casual_response)
175
 
176
- # # Process analysis operations
177
- # for operation in response.analysis_operations:
178
- # # Execute the code
179
- # result = self.execute_code(operation.code.code)
180
 
181
- # # Add operation description
182
- # output_parts.append(f"\n{operation.description}:")
183
 
184
- # # Add output or error
185
- # if result['error']:
186
- # output_parts.append(f"Error: {result['error']['message']}")
187
- # else:
188
- # output_parts.append(result['output'].strip())
189
-
190
- # # Process charts if they exist
191
- # if response.charts:
192
- # output_parts.append("\nVisualizations:")
193
-
194
- # for chart in response.charts:
195
- # if chart.code:
196
- # # Execute the chart code
197
- # result = self.execute_code(chart.code)
198
-
199
- # if result['plots']:
200
- # # Save each generated plot and get dummy URL
201
- # for plot_data in result['plots']:
202
- # dummy_url = self.save_plot_dummy(plot_data, chart.image_description)
203
- # output_parts.append(f"\n{chart.image_description}")
204
- # output_parts.append(f"![{chart.image_description}]({dummy_url})")
205
- # elif result['error']:
206
- # output_parts.append(f"\nError generating {chart.image_description}: {result['error']['message']}")
207
-
208
- # return "\n".join(output_parts)
209
-
210
- def process_response(self, response: CsvChatResult) -> str:
211
- """
212
- Process the CsvChatResult response and generate formatted output
213
- with markdown code blocks for structured data.
214
- """
215
- output_parts = []
216
-
217
- # Add casual response
218
- output_parts.append(response.casual_response)
219
-
220
- # Process analysis operations
221
- for operation in response.analysis_operations:
222
- # Execute the code
223
- result = self.execute_code(operation.code.code)
224
-
225
- # Add operation description
226
- output_parts.append(f"\n{operation.description}:")
227
-
228
- # Add output or error with markdown wrapping
229
- if result['error']:
230
- output_parts.append("```python\n" + f"Error: {result['error']['message']}" + "\n```")
231
- else:
232
- output = result['output'].strip()
233
- if self._looks_like_structured_data(output): # New helper method
234
- output_parts.append("```python\n" + output + "\n```")
235
  else:
236
- output_parts.append(output)
237
-
238
- # Process charts remains the same
239
- if response.charts:
240
- output_parts.append("\nVisualizations:")
241
- for chart in response.charts:
242
- if chart.code:
243
- result = self.execute_code(chart.code)
244
- if result['plots']:
245
- for plot_data in result['plots']:
246
- dummy_url = self.save_plot_dummy(plot_data, chart.image_description)
247
- output_parts.append(f"\n{chart.image_description}")
248
- output_parts.append(f"![{chart.image_description}]({dummy_url})")
249
- elif result['error']:
250
- output_parts.append("```python\n" + f"Error generating {chart.image_description}: {result['error']['message']}" + "\n```")
251
-
252
- return "\n".join(output_parts)
253
-
254
- def _looks_like_structured_data(self, output: str) -> bool:
255
- """Helper to detect JSON-like or array-like output"""
256
- output = output.strip()
257
- return (
258
- output.startswith('{') and output.endswith('}') or # JSON object
259
- output.startswith('[') and output.endswith(']') or # Array
260
- '\n' in output and '=' in output # Python console output
261
- )
 
 
 
1
+ import os
2
+ from supabase import create_client, Client
3
+ from dotenv import load_dotenv
4
  import uuid
5
  import matplotlib.pyplot as plt
6
  from pathlib import Path
 
17
  import scipy.stats as stats
18
  from pydantic import BaseModel
19
 
20
+ from supabase_service import upload_file_to_supabase
21
+
22
+ # Load environment variables from .env file
23
+ load_dotenv()
24
 
25
  class CodeResponse(BaseModel):
26
  """Container for code-related responses"""
 
143
  'plots': plots
144
  }
145
 
146
+ async def save_plot_to_supabase(self, plot_data: bytes, description: str, chat_id: str) -> str:
147
  """
148
+ Save plot to Supabase storage and return the public URL
149
 
150
  Args:
151
  plot_data (bytes): Image data in bytes
152
  description (str): Description of the plot
153
+ chat_id (str): ID of the chat session
154
 
155
  Returns:
156
+ str: Public URL of the uploaded chart
157
  """
158
  # Generate unique filename
159
  filename = f"chart_{uuid.uuid4().hex}.png"
160
  filepath = self.charts_folder / filename
161
 
162
+ # Save the plot locally first
163
  with open(filepath, 'wb') as f:
164
  f.write(plot_data)
165
 
166
+ try:
167
+ # Upload to Supabase
168
+ public_url = await upload_file_to_supabase(
169
+ file_path=str(filepath),
170
+ file_name=filename,
171
+ chat_id=chat_id
172
+ )
173
+
174
+ # Remove the local file after upload
175
+ os.remove(filepath)
176
+
177
+ return public_url
178
+ except Exception as e:
179
+ # Clean up local file if upload fails
180
+ if os.path.exists(filepath):
181
+ os.remove(filepath)
182
+ raise Exception(f"Failed to upload plot to Supabase: {e}")
183
+
184
+ def _looks_like_structured_data(self, output: str) -> bool:
185
+ """Helper to detect JSON-like or array-like output"""
186
+ output = output.strip()
187
+ return (
188
+ output.startswith('{') and output.endswith('}') or # JSON object
189
+ output.startswith('[') and output.endswith(']') or # Array
190
+ '\n' in output and '=' in output # Python console output
191
+ )
192
 
193
+ async def process_response(self, response: CsvChatResult, chat_id: str) -> str:
194
+ """
195
+ Process the CsvChatResult response and generate formatted output
196
+ with markdown code blocks for structured data.
197
 
198
+ Args:
199
+ response (CsvChatResult): Response from CSV analysis
200
+ chat_id (str): ID of the chat session
201
 
202
+ Returns:
203
+ str: Formatted output with results and image URLs
204
+ """
205
+ output_parts = []
206
 
207
+ # Add casual response
208
+ output_parts.append(response.casual_response)
209
 
210
+ # Process analysis operations
211
+ for operation in response.analysis_operations:
212
+ # Execute the code
213
+ result = self.execute_code(operation.code.code)
214
 
215
+ # Add operation description
216
+ output_parts.append(f"\n{operation.description}:")
217
 
218
+ # Add output or error with markdown wrapping
219
+ if result['error']:
220
+ output_parts.append("```python\n" + f"Error: {result['error']['message']}" + "\n```")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  else:
222
+ output = result['output'].strip()
223
+ if self._looks_like_structured_data(output):
224
+ output_parts.append("```python\n" + output + "\n```")
225
+ else:
226
+ output_parts.append(output)
227
+
228
+ # Process charts
229
+ if response.charts:
230
+ output_parts.append("\nVisualizations:")
231
+ for chart in response.charts:
232
+ if chart.code:
233
+ result = self.execute_code(chart.code)
234
+ if result['plots']:
235
+ for plot_data in result['plots']:
236
+ try:
237
+ public_url = await self.save_plot_to_supabase(
238
+ plot_data=plot_data,
239
+ description=chart.image_description,
240
+ chat_id=chat_id
241
+ )
242
+ output_parts.append(f"\n{chart.image_description}")
243
+ output_parts.append(f"![{chart.image_description}]({public_url})")
244
+ except Exception as e:
245
+ output_parts.append(f"\nError uploading chart: {str(e)}")
246
+ elif result['error']:
247
+ output_parts.append("```python\n" + f"Error generating {chart.image_description}: {result['error']['message']}" + "\n```")
248
+
249
+ return "\n".join(output_parts)
together_ai_llama_agent.py CHANGED
@@ -113,7 +113,7 @@ def create_csv_agent(df: pd.DataFrame, max_retries: int = 1) -> Agent:
113
  raise RuntimeError(f"Failed to create agent after {max_retries} attempts")
114
 
115
 
116
- async def query_csv_agent(csv_url: str, question: str) -> str:
117
  """Query the CSV agent with a DataFrame and question and return formatted output"""
118
 
119
  # Get the DataFrame from the CSV URL
@@ -140,6 +140,6 @@ async def query_csv_agent(csv_url: str, question: str) -> str:
140
  print("Chat Result Original Object:", chat_result)
141
 
142
  # Process and format the response
143
- formatted_output = executor.process_response(chat_result)
144
 
145
  return formatted_output
 
113
  raise RuntimeError(f"Failed to create agent after {max_retries} attempts")
114
 
115
 
116
+ async def query_csv_agent(csv_url: str, question: str, chat_id: str) -> str:
117
  """Query the CSV agent with a DataFrame and question and return formatted output"""
118
 
119
  # Get the DataFrame from the CSV URL
 
140
  print("Chat Result Original Object:", chat_result)
141
 
142
  # Process and format the response
143
+ formatted_output = executor.process_response(chat_result, chat_id)
144
 
145
  return formatted_output