diff --git a/app/agent/data_analysis.py b/app/agent/data_analysis.py index 156a90e..f3e323d 100644 --- a/app/agent/data_analysis.py +++ b/app/agent/data_analysis.py @@ -4,11 +4,9 @@ from app.agent.toolcall import ToolCallAgent from app.config import config from app.prompt.visualization import NEXT_STEP_PROMPT, SYSTEM_PROMPT from app.tool import Terminate, ToolCollection +from app.tool.chart_visualization.chart_prepare import VisualizationPrepare from app.tool.chart_visualization.chart_visualization import ChartVisualization from app.tool.chart_visualization.normal_python_execute import NormalPythonExecute -from app.tool.chart_visualization.chart_prepare import ( - VisualizationPrepare, -) class DataAnalysis(ToolCallAgent): @@ -34,8 +32,8 @@ class DataAnalysis(ToolCallAgent): available_tools: ToolCollection = Field( default_factory=lambda: ToolCollection( NormalPythonExecute(), - VisualizationPrepare(), - ChartVisualization(), + # VisualizationPrepare(), + # ChartVisualization(), Terminate(), ) ) diff --git a/app/tool/chart_visualization/normal_python_execute.py b/app/tool/chart_visualization/normal_python_execute.py index 1c0aa2f..c98a519 100644 --- a/app/tool/chart_visualization/normal_python_execute.py +++ b/app/tool/chart_visualization/normal_python_execute.py @@ -6,26 +6,19 @@ class NormalPythonExecute(PythonExecute): name: str = "common_python_execute" description: str = ( - """Executes Python code strings to tasks such as data process and data report""" + "Execute Python code for in-depth data analysis without direct visualization. " + "The code should generate a comprehensive text-based report containing dataset overview, " + "column details, basic statistics, derived metrics, day-of-week comparisons, outliers, and key insights. " + "Use print() for all outputs so the analysis (including sections like 'Dataset Overview' or 'Preprocessing Results') " + "is clearly visible, and save any final report or processed files to config.workspace. " + "Include try-except blocks for error handling, and provide the code as a single string with '\\n' for line breaks." ) parameters: dict = { "type": "object", "properties": { "code": { "type": "string", - "description": """The Python code to execute. Note: -1. Only outputs from print() are visible; function return values are not captured. Use print() statements to display results -2. Do data process (cleaning / transform) saved in *.csv -3. Generate a data analysis report in html""", - }, - "code_type": { - "description": "code type", - "type": "string", - "enum": ["process", "report", "others"], }, }, "required": ["code"], } - - async def execute(self, code: str, code_type: str, timeout=5): - return await super().execute(code, timeout) diff --git a/app/tool/chart_visualization/test/amazon_fashion_analysis.py b/app/tool/chart_visualization/test/amazon_fashion_analysis.py new file mode 100644 index 0000000..84b9bc3 --- /dev/null +++ b/app/tool/chart_visualization/test/amazon_fashion_analysis.py @@ -0,0 +1,48 @@ +import asyncio +import time + +from app.agent.data_analysis import DataAnalysis +from app.agent.manus import Manus +from app.flow.base import FlowType +from app.flow.flow_factory import FlowFactory +from app.logger import logger + + +async def run_flow(): + agents = { + # "manus": Manus(), + "visactor": DataAnalysis(), + } + + try: + prompt = """Here's last month's sales data from my Amazon store in './data/amazon_sales_jan2025.xlsx'. Could you analyze it?""" + + flow = FlowFactory.create_flow( + flow_type=FlowType.PLANNING, + agents=agents, + ) + logger.warning("Processing your request...") + + try: + start_time = time.time() + result = await asyncio.wait_for( + flow.execute(prompt), + timeout=3600, # 60 minute timeout for the entire execution + ) + elapsed_time = time.time() - start_time + logger.info(f"Request processed in {elapsed_time:.2f} seconds") + logger.info(result) + except asyncio.TimeoutError: + logger.error("Request processing timed out after 1 hour") + logger.info( + "Operation terminated due to timeout. Please try a simpler request." + ) + + except KeyboardInterrupt: + logger.info("Operation cancelled by user.") + except Exception as e: + logger.error(f"Error: {str(e)}") + + +if __name__ == "__main__": + asyncio.run(run_flow())