From 67bb90d1788fc59f192b5a3a038e545e73451abd Mon Sep 17 00:00:00 2001 From: seeker Date: Wed, 10 Jul 2024 22:14:35 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E6=8F=90=E7=A4=BA=E8=AF=8D=20ex=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- metagpt/prompts/di/swe_agent.py | 108 ++++++++++++------ metagpt/tools/libs/git.py | 36 +++--- metagpt/tools/libs/terminal.py | 5 +- .../tools/swe_agent_commands/setup_default.sh | 1 - 4 files changed, 99 insertions(+), 51 deletions(-) diff --git a/metagpt/prompts/di/swe_agent.py b/metagpt/prompts/di/swe_agent.py index 78a8ce846..c4db3b785 100644 --- a/metagpt/prompts/di/swe_agent.py +++ b/metagpt/prompts/di/swe_agent.py @@ -5,7 +5,7 @@ https://github.com/princeton-nlp/SWE-agent/tree/main/config/configs """ SWE_AGENT_SYSTEM_TEMPLATE = """ -SETTING: You are an autonomous programmer, and you're working directly in the environment line with a special interface.Let's work step by step. +SETTING: You are an autonomous programmer, and you're working directly in the environment line with a special interface. The special interface consists of a file editor that shows you 100 lines of a file at a time. @@ -33,7 +33,7 @@ You should only include a *SINGLE* command in the command section and then wait If you'd like to issue two commands at once, PLEASE DO NOT DO THAT! Please instead first submit just the first command, and then after receiving a response you'll be able to issue the second command. Remember, YOU CAN ONLY ENTER ONE COMMAND AT A TIME. You should always wait for feedback after every command. -You can use any bash commands you want (e.g., find, grep, cat, ls, cd) or any custom special tools (including `edit`) by calling Bash.run. Edit all the files you need, but make sure to PRIORITIZE the `Available Commands` provided to accomplish your tasks,such as `git_push`. +You can use any bash commands you want (e.g., find, grep, cat, ls, cd) or any custom special tools (including `edit`) by calling Bash.run. Edit all the files you need. You should carefully observe the behavior and results of the previous action, and avoid triggering repeated errors. However, the Bash.run does NOT support interactive session commands (e.g. python, vim), so please do not invoke them. @@ -50,69 +50,111 @@ MINIMAL_EXAMPLE = """ ## Example of a actions trajectory User Requirement and Issue: Fix the bug in the repo. Because the environment is not available, you DO NOT need to run and modify any existing test case files or add new test case files to ensure that the bug is fixed. -### Read and understand issue(Require): -[{{ +### Read and understand issue: +Thought: Firstly, I need to review the detailed information of this issue in order to understand the problem that needs fixing. +{{ "command_name": "Browser.goto", "args": {{ "url": "https://github.com/geekan/MetaGPT/issues/1275" }} -}}] +}} -> ### Locate issue(Require): Locate the issue in the code by searching for the relevant file, function, or class and open the file to view the code. -[{{ +Thought: I need to come under the repo path +{{ "command_name": "Bash.run", "args": {{ - "cmd": "cd /workspace/django__django_3.0" + "cmd": "cd /workspace/MetaGPT" }} -}}] +}} -> -Bash.run(cmd='search_dir_and_preview ASCIIUsernameValidator') -[{{ +Thought: Let's start by locating the `openai_api.py` file.\nFirst, let's search for the `openai_api.py` file. +{{ "command_name": "Bash.run", "args": {{ - "cmd": "open /workspace/django__django_3.0/django/contrib/auth/validators.py" + "cmd": "find_file 'openai_api.py'" }} -}}] +}} +-> + +Thought: We have located both the `openai_api.py` file. Let's start by opening the `openai_api.py` file to apply the necessary changes.", +{{ + "command_name": "Bash.run", + "args": {{ + "cmd": "open '/workspace/MetaGPT/provider/openai_api.py'" + }} +}} -> ### Fix the Bug(Require): Fix the bug in the code by editing the relevant function, class or code snippet. -[{{ +Thought: Let's edit the apow function to include the Pow case in the isinstance check. +{{ "command_name": "Bash.run", "args": {{ - "cmd": "edit 10:20 < +Thought: Due to a syntax error related to an undefined name 'Image', we need to address this issue even though it is not directly related to our work. Let's try importing the package to fix it. +{{ + "command_name": "Bash.run", + "args": {{ + "cmd": "edit 14:14 < -### Push the Changes: Pushes changes from a local Git repository to its remote counterpart. -[{{ +### Save the Changes (Required): After all changes have been made, save them to the repository. +> You must choose one of the following two methods. + +#### Just save the changes locally, it only need one action. +Thought: The bug has been fixed. Let's submit the changes. +{{ + "command_name": "Bash.run", + "args": {{ + "cmd": "submit" + }} +}} +-> + +#### Save the changes and commit them to the remote repository. + +##### Push the changes from the local repository to the remote repository. +Thought: All changes have been saved, let's push the code to the remote repository. +{{ "command_name": "git_push", "args": {{ - "local_path": "/workspace/django__django_3.0/django/contrib/auth", + "local_path": "/workspace/MetaGPT", "app_name": "github", - "comments": "Fix: produced TypeError: openai.types.completion_usage.CompletionUsage() argument after ** must be a mapping, not NoneType", + "comments": "Fix Issue #1275: produced TypeError: openai.types.completion_usage.CompletionUsage() argument after ** must be a mapping, not NoneType"", "new_branch": "test-fix" }} -}}] +}} +-> -### Create pull request +##### Create a pull request (Optional): Merge the changes from the new branch into the master branch. +Thought: Now that the changes have been pushed to the remote repository, due to the user's requirement, let's create a pull request to merge the changes into the master branch. [{{ "command_name": "git_create_pull", "args": {{ "base": "master", "head": "test-fix", - "base_repo_name": "Justin-ZL/langchain", + "base_repo_name": "garylin2099/MetaGPT", + "head_repo_name": "seeker-jie/MetaGPT", "app_name": "github", - "title": "Fix Issue #1275: produced TypeError: openai.types.completion_usage.CompletionUsage() argument after ** must be a mapping, not NoneTyp", - "body": "This pull request addresses issue #1275 by producing TypeError: openai.types.completion_usage.CompletionUsage() argument after ** must be a mapping, not NoneTyp." - }} + "title": "Fix Issue #1275: produced TypeError: openai.types.completion_usage.CompletionUsage() argument after ** must be a mapping, not NoneType"", + "body": "This pull request addresses issue #1275 by ensuring that chunk.usage is not None before passing it to CompletionUsage." + }} }}] -> -[{{ - "command_name": "end", -}}] + +### Finally +Thought: All task has been done, let's end the conversation. +{{ + "command_name": "end" +}} """ @@ -177,11 +219,14 @@ IMPORTANT_TIPS = """ - If a search command fails, modify the search criteria and check for typos or incorrect paths, then try again. - Based on feedback of observation or bash command in trajectory to guide adjustments in your search strategy. -13. If the task results in succeed, use command `git_push` to push the results in local,then use command `git_create_pull` to create PR. +13. Save the code change: + - If you need to submit changes to the remote repository, first use the regular git commit command to save the changes locally, then select a command from the `Available Commands: [git_push, git_create_pull]` to submit the changes to the remote repository. + + - If you don't need to submit code changes to the remote repository. use the command Bash.run('submit') to commit the changes locally. 14. If provided an issue link, you MUST go to the issue page using Browser tool to understand the issue before starting your fix. -15. When the edit fails, try to enlarge the starting line. +15. When the edit fails, try to enlarge the starting line, The edit function needs to use `Bash.Run` call. """ NEXT_STEP_TEMPLATE = f""" @@ -199,6 +244,5 @@ The current bash state is: (Open file: {{open_file}}) (Current directory: {{working_dir}}) -Avoid repeating the same command. Instead, please think about the current situation and provide the next bash command to execute in JSON format:" - +Avoid repeating the same command. Instead, please think about the current situation and provide the next bash command to execute in JSON format" """ diff --git a/metagpt/tools/libs/git.py b/metagpt/tools/libs/git.py index 4606b5815..676e9125a 100644 --- a/metagpt/tools/libs/git.py +++ b/metagpt/tools/libs/git.py @@ -9,9 +9,10 @@ from github.Issue import Issue from github.PullRequest import PullRequest from metagpt.tools.tool_registry import register_tool +from metagpt.utils.git_repository import GitBranch -@register_tool(tags=["software development", "git", "Commit the changes and push to remote git repository."]) +@register_tool(tags=["software development", "git", "Push to remote git repository."]) async def git_push( local_path: Union[str, Path], app_name: str, @@ -22,22 +23,23 @@ async def git_push( Pushes changes from a local Git repository to its remote counterpart. Args: - local_path (Union[str, Path]): The path to the local Git repository. - app_name (str): The name of the application where the repository is hosted. For example, "github", "gitlab", "bitbucket", etc. - comments (str, optional): The commit message to use. Defaults to "Commit". + local_path (Union[str, Path]): The absolute path to the local Git repository. + app_name (str): The name of the platform hosting the repository (e.g., "github", "gitlab", "bitbucket"). + comments (str, optional): Comments to be associated with the push. Defaults to "Commit". new_branch (str, optional): The name of the new branch to create and push changes to. If not provided, changes will be pushed to the current branch. Defaults to "". Returns: GitBranch: The branch to which the changes were pushed. + Raises: ValueError: If the provided local_path does not point to a valid Git repository. Example: >>> url = "https://github.com/iorisa/snake-game.git" >>> local_path = await git_clone(url=url) - >>> app_name="github" - >>> comments = "Archive" + >>> app_name = "github" + >>> comments = "Commit" >>> new_branch = "feature/new" >>> branch = await git_push(local_path=local_path, app_name=app_name, comments=comments, new_branch=new_branch) >>> base = branch.base @@ -45,8 +47,8 @@ async def git_push( >>> repo_name = branch.repo_name >>> print(f"base branch:'{base}', head branch:'{head}', repo_name:'{repo_name}'") base branch:'master', head branch:'feature/new', repo_name:'iorisa/snake-game' - """ + from metagpt.tools.libs import get_env from metagpt.utils.git_repository import GitRepository @@ -64,9 +66,9 @@ async def git_push( async def git_create_pull( base: str, head: str, - base_repo_name: str, app_name: str, - head_repo_name: Optional[str] = None, + base_repo_name: str, + head_repo_name: str = None, title: Optional[str] = None, body: Optional[str] = None, issue: Optional[Issue] = None, @@ -75,14 +77,14 @@ async def git_create_pull( Creates a pull request on a Git repository. Use this tool in priority over Browser to create a pull request. Args: - base (str): The base branch of the pull request. - head (str): The head branch of the pull request. - base_repo_name (str): The full repository name (user/repo) where the pull request will be created. - app_name (str): The name of the application where the repository is hosted. For example, "github", "gitlab", "bitbucket", etc. - head_repo_name (Optional[str], optional): The full repository name (user/repo) where the pull request will merge from. Defaults to None. - title (Optional[str], optional): The title of the pull request. Defaults to None. - body (Optional[str], optional): The body of the pull request. Defaults to None. - issue (Optional[Issue], optional): The related issue of the pull request. Defaults to None. + base (str): The name of the base branch where the pull request will be merged. + head (str): The name of the branch that contains the changes for the pull request. + app_name (str): The name of the platform hosting the repository (e.g., "github", "gitlab", "bitbucket"). + base_repo_name (str): The full name of the target repository (in the format "user/repo") where the pull request will be created. + head_repo_name (Optional[str]): The full name of the source repository (in the format "user/repo") from which the changes will be pulled. + title (Optional[str]): The title of the pull request. Defaults to None. + body (Optional[str]): The description or body content of the pull request. Defaults to None. + issue (Optional[Issue]): An optional issue related to the pull request. Defaults to None. Example: >>> # create pull request diff --git a/metagpt/tools/libs/terminal.py b/metagpt/tools/libs/terminal.py index 8d44c13e6..c23cc1a7f 100644 --- a/metagpt/tools/libs/terminal.py +++ b/metagpt/tools/libs/terminal.py @@ -28,7 +28,7 @@ class Terminal: async def _start_process(self): # Start a persistent shell process self.process = await asyncio.create_subprocess_exec( - *self.shell_command, stdin=PIPE, stdout=PIPE, stderr=PIPE, executable="/bin/bash" + *self.shell_command, stdin=PIPE, stdout=PIPE, stderr=PIPE, executable="bash" ) await self._check_state() @@ -227,6 +227,9 @@ class Bash(Terminal): end_line (int): The line number to end the edit at (inclusive), starting from 1. replacement_text (str): The text to replace the current selection with, must conform to PEP8 standards. + - submit + Submits your current code locally. it can only be executed once, the last action before the `end`. + Note: Make sure to use these functions as per their defined arguments and behaviors. """ if not self.start_flag: diff --git a/metagpt/tools/swe_agent_commands/setup_default.sh b/metagpt/tools/swe_agent_commands/setup_default.sh index dc3b335df..5e02fad5d 100644 --- a/metagpt/tools/swe_agent_commands/setup_default.sh +++ b/metagpt/tools/swe_agent_commands/setup_default.sh @@ -17,4 +17,3 @@ source $REPO_ROOT_DIR/metagpt/tools/swe_agent_commands/search.sh source $REPO_ROOT_DIR/metagpt/tools/swe_agent_commands/edit_linting.sh export SWE_CMD_WORK_DIR="$REPO_ROOT_DIR/workspace/swe_agent_workdir" -#sudo chmod 777 $REPO_ROOT_DIR/workspace/swe_agent_workdir