Soumik555 commited on
Commit
026703c
·
1 Parent(s): 6065669

max length from 10 --> 8

Browse files
Files changed (1) hide show
  1. python_code_executor_service.py +54 -112
python_code_executor_service.py CHANGED
@@ -27,28 +27,22 @@ class CodeResponse(BaseModel):
27
  language: str = "python"
28
  code: str
29
 
30
-
31
  class ChartSpecification(BaseModel):
32
  """Details about requested charts"""
33
  image_description: str
34
  code: Optional[str] = None
35
 
36
-
37
  class AnalysisOperation(BaseModel):
38
  """Container for a single analysis operation with its code and result"""
39
  code: CodeResponse
40
  result_var: str
41
 
42
-
43
  class CsvChatResult(BaseModel):
44
  """Structured response for CSV-related AI interactions"""
45
  casual_response: str
46
- # analysis_operations: Optional[AnalysisOperation]
47
- # charts: Optional[ChartSpecification]
48
  analysis_operations: Optional[List[AnalysisOperation]]
49
  charts: Optional[List[ChartSpecification]]
50
 
51
-
52
  class PythonExecutor:
53
  """Handles execution of Python code with comprehensive data analysis libraries"""
54
 
@@ -196,120 +190,68 @@ class PythonExecutor:
196
  return str(result)
197
 
198
  async def process_response(self, response: CsvChatResult, chat_id: str) -> str:
199
- """Process the response with proper variable handling and error checking"""
200
- output_parts = [response.casual_response]
201
 
202
- # Process analysis operations if they exist
203
- if response.analysis_operations is not None:
204
- for operation in response.analysis_operations:
205
- try:
206
- if operation and operation.code and operation.code.code:
207
- execution_result = self.execute_code(operation.code.code)
208
 
209
- # Get the result from locals
210
- result = self.exec_locals.get(operation.result_var)
211
 
212
- if execution_result.get('error'):
213
- output_parts.append(f"\n❌ Error in operation '{operation.result_var}':")
214
- output_parts.append("```python\n" + execution_result['error']['message'] + "\n```")
215
- elif result is not None:
216
- # Handle empty/None results
217
- if result is None or (hasattr(result, '__len__') and len(result) == 0):
218
- output_parts.append(f"\n⚠️ Values are missing - Operation '{operation.result_var}' returned no data")
 
 
 
219
  else:
220
- output_parts.append(f"\n🔹 Result for '{operation.result_var}':")
221
- output_parts.append("```python\n" + self._format_result(result) + "\n```")
 
222
  else:
223
- output_str = execution_result.get('output', '').strip()
224
- if output_str:
225
- output_parts.append("```\n" + output_str + "\n```")
226
- else:
227
- output_parts.append("\n⚠️ Invalid analysis operation - missing code or result variable")
228
- except Exception as e:
229
- output_parts.append(f"\n❌ Error processing analysis operation: {str(e)}")
230
- if operation:
231
- output_parts.append(f"Operation: {operation.result_var}")
232
 
233
  # Process charts if they exist
234
  if response.charts is not None:
235
- for chart in response.charts:
236
- try:
237
- if chart and (chart.code or chart.image_description):
238
- if chart.code:
239
- chart_result = self.execute_code(chart.code)
240
- if chart_result.get('plots'):
241
- for plot_data in chart_result['plots']:
242
- try:
243
- public_url = await self.save_plot_to_supabase(
244
- plot_data=plot_data,
245
- description=chart.image_description,
246
- chat_id=chat_id
247
- )
248
- output_parts.append(f"\n🖼️ {chart.image_description}")
249
- output_parts.append(f"![{chart.image_description}]({public_url})")
250
- except Exception as e:
251
- output_parts.append(f"\n⚠️ Error uploading chart: {str(e)}")
252
- elif chart_result.get('error'):
253
- output_parts.append("```python\n" + f"Error generating {chart.image_description}: {chart_result['error']['message']}" + "\n```")
 
 
254
  else:
255
- output_parts.append(f"\n⚠️ No chart generated for '{chart.image_description}'")
256
  else:
257
- output_parts.append(f"\n⚠️ No code provided for chart: {chart.image_description}")
258
- else:
259
- output_parts.append("\n⚠️ Invalid chart specification")
260
- except Exception as e:
261
- output_parts.append(f"\n❌ Error processing chart: {str(e)}")
262
 
263
- return "\n".join(output_parts)
264
-
265
- # async def process_response(self, response: CsvChatResult, chat_id: str) -> str:
266
- # """Process the response with proper variable handling"""
267
- # output_parts = [response.casual_response]
268
-
269
- # # Process analysis operations first
270
- # for operation in response.analysis_operations:
271
- # execution_result = self.execute_code(operation.code.code)
272
-
273
- # # Get the result from locals
274
- # result = self.exec_locals.get(operation.result_var)
275
-
276
- # if execution_result['error']:
277
- # output_parts.append(f"\n❌ Error in operation '{operation.result_var}':")
278
- # output_parts.append("```python\n" + execution_result['error']['message'] + "\n```")
279
- # elif result is not None:
280
- # # Handle empty/None results
281
- # if result is None or (hasattr(result, '__len__') and len(result) == 0):
282
- # output_parts.append(f"\n⚠️ Values are missing - Operation '{operation.result_var}' returned no data")
283
- # else:
284
- # output_parts.append(f"\n🔹 Result for '{operation.result_var}':")
285
- # output_parts.append("```python\n" + self._format_result(result) + "\n```")
286
- # else:
287
- # output_str = execution_result['output'].strip()
288
- # if output_str:
289
- # output_parts.append("```\n" + output_str + "\n```")
290
-
291
-
292
- # # Process charts after all operations
293
- # if response.charts:
294
- # output_parts.append("\n📊 Visualizations:")
295
- # for chart in response.charts:
296
- # if chart.code:
297
- # chart_result = self.execute_code(chart.code)
298
- # if chart_result['plots']:
299
- # for plot_data in chart_result['plots']:
300
- # try:
301
- # public_url = await self.save_plot_to_supabase(
302
- # plot_data=plot_data,
303
- # description=chart.image_description,
304
- # chat_id=chat_id
305
- # )
306
- # output_parts.append(f"\n🖼️ {chart.image_description}")
307
- # output_parts.append(f"![{chart.image_description}]({public_url})")
308
- # except Exception as e:
309
- # output_parts.append(f"\n⚠️ Values are missing - Error uploading chart: {str(e)}")
310
- # elif chart_result['error']:
311
- # output_parts.append("```python\n" + f"Error generating {chart.image_description}: {chart_result['error']['message']}" + "\n```")
312
- # else:
313
- # output_parts.append(f"\n⚠️ Values are missing - No chart generated for '{chart.image_description}'")
314
-
315
- # return "\n".join(output_parts)
 
27
  language: str = "python"
28
  code: str
29
 
 
30
  class ChartSpecification(BaseModel):
31
  """Details about requested charts"""
32
  image_description: str
33
  code: Optional[str] = None
34
 
 
35
  class AnalysisOperation(BaseModel):
36
  """Container for a single analysis operation with its code and result"""
37
  code: CodeResponse
38
  result_var: str
39
 
 
40
  class CsvChatResult(BaseModel):
41
  """Structured response for CSV-related AI interactions"""
42
  casual_response: str
 
 
43
  analysis_operations: Optional[List[AnalysisOperation]]
44
  charts: Optional[List[ChartSpecification]]
45
 
 
46
  class PythonExecutor:
47
  """Handles execution of Python code with comprehensive data analysis libraries"""
48
 
 
190
  return str(result)
191
 
192
  async def process_response(self, response: CsvChatResult, chat_id: str) -> str:
193
+ """Process the response with proper variable handling and error checking"""
194
+ output_parts = [response.casual_response]
195
 
196
+ # Process analysis operations if they exist
197
+ if response.analysis_operations is not None:
198
+ for operation in response.analysis_operations:
199
+ try:
200
+ if operation and operation.code and operation.code.code:
201
+ execution_result = self.execute_code(operation.code.code)
202
 
203
+ # Get the result from locals
204
+ result = self.exec_locals.get(operation.result_var)
205
 
206
+ if execution_result.get('error'):
207
+ output_parts.append(f"\n❌ Error in operation '{operation.result_var}':")
208
+ output_parts.append("```python\n" + execution_result['error']['message'] + "\n```")
209
+ elif result is not None:
210
+ # Handle empty/None results
211
+ if result is None or (hasattr(result, '__len__') and len(result) == 0):
212
+ output_parts.append(f"\n⚠️ Values are missing - Operation '{operation.result_var}' returned no data")
213
+ else:
214
+ output_parts.append(f"\n🔹 Result for '{operation.result_var}':")
215
+ output_parts.append("```python\n" + self._format_result(result) + "\n```")
216
  else:
217
+ output_str = execution_result.get('output', '').strip()
218
+ if output_str:
219
+ output_parts.append("```\n" + output_str + "\n```")
220
  else:
221
+ output_parts.append("\n⚠️ Invalid analysis operation - missing code or result variable")
222
+ except Exception as e:
223
+ output_parts.append(f"\n Error processing analysis operation: {str(e)}")
224
+ if operation:
225
+ output_parts.append(f"Operation: {operation.result_var}")
 
 
 
 
226
 
227
  # Process charts if they exist
228
  if response.charts is not None:
229
+ for chart in response.charts:
230
+ try:
231
+ if chart and (chart.code or chart.image_description):
232
+ if chart.code:
233
+ chart_result = self.execute_code(chart.code)
234
+ if chart_result.get('plots'):
235
+ for plot_data in chart_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"\n⚠️ Error uploading chart: {str(e)}")
246
+ elif chart_result.get('error'):
247
+ output_parts.append("```python\n" + f"Error generating {chart.image_description}: {chart_result['error']['message']}" + "\n```")
248
+ else:
249
+ output_parts.append(f"\n⚠️ No chart generated for '{chart.image_description}'")
250
  else:
251
+ output_parts.append(f"\n⚠️ No code provided for chart: {chart.image_description}")
252
  else:
253
+ output_parts.append("\n⚠️ Invalid chart specification")
254
+ except Exception as e:
255
+ output_parts.append(f"\n Error processing chart: {str(e)}")
 
 
256
 
257
+ return "\n".join(output_parts)