import re from typing import Type, Optional, List from pydantic import BaseModel, Field from superagi.agent.agent_prompt_builder import AgentPromptBuilder from superagi.helper.error_handler import ErrorHandler from superagi.helper.prompt_reader import PromptReader from superagi.helper.token_counter import TokenCounter from superagi.lib.logger import logger from superagi.llms.base_llm import BaseLlm from superagi.models.agent_execution import AgentExecution from superagi.models.agent_execution_feed import AgentExecutionFeed from superagi.resource_manager.file_manager import FileManager from superagi.tools.base_tool import BaseTool from superagi.tools.tool_response_query_manager import ToolResponseQueryManager class ImproveCodeSchema(BaseModel): pass class ImproveCodeTool(BaseTool): """ Used to improve the already generated code by reading the code from the files Attributes: llm: LLM used for code generation. name : The name of the tool. description : The description of the tool. resource_manager: Manages the file resources. """ llm: Optional[BaseLlm] = None agent_id: int = None agent_execution_id: int = None name = "ImproveCodeTool" description = ( "This tool improves the generated code." ) args_schema: Type[ImproveCodeSchema] = ImproveCodeSchema resource_manager: Optional[FileManager] = None tool_response_manager: Optional[ToolResponseQueryManager] = None goals: List[str] = [] class Config: arbitrary_types_allowed = True def _execute(self) -> str: """ Execute the improve code tool. Returns: Improved code or error message. """ # Get all file names that the CodingTool has written file_names = self.resource_manager.get_files() logger.info(file_names) # Loop through each file for file_name in file_names: if '.txt' not in file_name and '.sh' not in file_name and '.json' not in file_name: # Read the file content content = self.resource_manager.read_file(file_name) # Generate a prompt from improve_code.txt prompt = PromptReader.read_tools_prompt(__file__, "improve_code.txt") # Combine the hint from the file, goals, and content prompt = prompt.replace("{goals}", AgentPromptBuilder.add_list_items_to_string(self.goals)) prompt = prompt.replace("{content}", content) # Add the file content to the chat completion prompt prompt = prompt + "\nOriginal Code:\n```\n" + content + "\n```" # Use LLM to generate improved code result = self.llm.chat_completion([{'role': 'system', 'content': prompt}]) if result is not None and 'error' in result and result['message'] is not None: ErrorHandler.handle_openai_errors(self.toolkit_config.session, self.agent_id, self.agent_execution_id, result['message']) # Extract the response first response = result.get('response') if not response: logger.info("RESPONSE NOT AVAILABLE") # Now extract the choices from response choices = response.get('choices') if not choices: logger.info("CHOICES NOT AVAILABLE") # Now you can safely extract the message content improved_content = choices[0]["message"]["content"] # improved_content = result["messages"][0]["content"] parsed_content = re.findall("```(?:\w*\n)?(.*?)```", improved_content, re.DOTALL) parsed_content_code = "\n".join(parsed_content) # Rewrite the file with the improved content save_result = self.resource_manager.write_file(file_name, parsed_content_code) if save_result.startswith("Error"): return save_result else: continue return f"All codes improved and saved successfully in: " + " ".join(file_names)