mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-05-15 11:02:36 +02:00
Merge branch 'feature-swe-agent' into 'mgx_ops'
update: 增加 swe agent 使用 git push 和 create pr 的能力 See merge request pub/MetaGPT!211
This commit is contained in:
commit
ef659d7dba
2 changed files with 31 additions and 44 deletions
|
|
@ -10,6 +10,7 @@ from metagpt.prompts.di.swe_agent import (
|
|||
SWE_AGENT_SYSTEM_TEMPLATE,
|
||||
)
|
||||
from metagpt.roles.di.role_zero import RoleZero
|
||||
from metagpt.tools.libs.git import git_create_pull, git_push
|
||||
from metagpt.tools.libs.terminal import Bash
|
||||
|
||||
|
||||
|
|
@ -21,7 +22,13 @@ class SWEAgent(RoleZero):
|
|||
_system_msg: str = SWE_AGENT_SYSTEM_TEMPLATE
|
||||
system_msg: list[str] = [_system_msg.format(WINDOW=_bash_window_size)]
|
||||
_instruction: str = NEXT_STEP_TEMPLATE
|
||||
tools: list[str] = ["Bash", "Browser:goto,scroll"]
|
||||
tools: list[str] = [
|
||||
"Bash",
|
||||
"Browser:goto,scroll",
|
||||
"RoleZero",
|
||||
"git_push",
|
||||
"git_create_pull",
|
||||
]
|
||||
terminal: Bash = Field(default_factory=Bash, exclude=True)
|
||||
output_diff: str = ""
|
||||
max_react_loop: int = 40
|
||||
|
|
@ -35,6 +42,15 @@ class SWEAgent(RoleZero):
|
|||
await self._parse_commands_for_eval()
|
||||
return res
|
||||
|
||||
def _update_tool_execution(self):
|
||||
self.tool_execution_map.update(
|
||||
{
|
||||
"Bash.run": self.terminal.run,
|
||||
"git_push": git_push,
|
||||
"git_create_pull": git_create_pull,
|
||||
}
|
||||
)
|
||||
|
||||
def _update_system_msg(self):
|
||||
"""
|
||||
Sets the system message for the SWE agent.
|
||||
|
|
@ -90,8 +106,5 @@ class SWEAgent(RoleZero):
|
|||
except Exception as e:
|
||||
logger.error(f"Error during submission: {e}")
|
||||
|
||||
def _update_tool_execution(self):
|
||||
self.tool_execution_map.update({"Bash.run": self.terminal.run})
|
||||
|
||||
def _retrieve_experience(self) -> str:
|
||||
return MINIMAL_EXAMPLE
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from metagpt.tools.tool_registry import register_tool
|
|||
@register_tool(tags=["software development", "git", "Commit the changes and push to remote git repository."])
|
||||
async def git_push(
|
||||
local_path: Union[str, Path],
|
||||
access_token: str,
|
||||
app_name: str,
|
||||
comments: str = "Commit",
|
||||
new_branch: str = "",
|
||||
) -> "GitBranch":
|
||||
|
|
@ -23,7 +23,7 @@ async def git_push(
|
|||
|
||||
Args:
|
||||
local_path (Union[str, Path]): The path to the local Git repository.
|
||||
access_token (str): The access token for authentication. Use `get_env` to get access token.
|
||||
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".
|
||||
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 "".
|
||||
|
|
@ -36,11 +36,10 @@ async def git_push(
|
|||
Example:
|
||||
>>> url = "https://github.com/iorisa/snake-game.git"
|
||||
>>> local_path = await git_clone(url=url)
|
||||
>>> from metagpt.tools.libs import get_env
|
||||
>>> access_token = await get_env(key="access_token", app_name="github") # Read access token from enviroment variables.
|
||||
>>> app_name="github"
|
||||
>>> comments = "Archive"
|
||||
>>> new_branch = "feature/new"
|
||||
>>> branch = await git_push(local_path=local_path, access_token=access_token, comments=comments, new_branch=new_branch)
|
||||
>>> branch = await git_push(local_path=local_path, app_name=app_name, comments=comments, new_branch=new_branch)
|
||||
>>> base = branch.base
|
||||
>>> head = branch.head
|
||||
>>> repo_name = branch.repo_name
|
||||
|
|
@ -48,12 +47,15 @@ async def git_push(
|
|||
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
|
||||
|
||||
if not GitRepository.is_git_dir(local_path):
|
||||
raise ValueError("Invalid local git repository")
|
||||
|
||||
repo = GitRepository(local_path=local_path, auto_init=False)
|
||||
# Read access token from environment variables.
|
||||
access_token = await get_env(key="access_token", app_name=app_name)
|
||||
branch = await repo.push(new_branch=new_branch, comments=comments, access_token=access_token)
|
||||
return branch
|
||||
|
||||
|
|
@ -63,7 +65,7 @@ async def git_create_pull(
|
|||
base: str,
|
||||
head: str,
|
||||
base_repo_name: str,
|
||||
access_token: str,
|
||||
app_name: str,
|
||||
head_repo_name: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
body: Optional[str] = None,
|
||||
|
|
@ -76,43 +78,13 @@ async def git_create_pull(
|
|||
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.
|
||||
access_token (str): The access token for authentication. Use `get_env` to get access token.
|
||||
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.
|
||||
|
||||
Example:
|
||||
>>> # push and create pull
|
||||
>>> url = "https://github.com/iorisa/snake-game.git"
|
||||
>>> local_path = await git_clone(url=url)
|
||||
>>> from metagpt.tools.libs import get_env
|
||||
>>> access_token = await get_env(key="access_token", app_name="github")
|
||||
>>> comments = "Archive"
|
||||
>>> new_branch = "feature/new"
|
||||
>>> branch = await git_push(local_path=local_path, access_token=access_token, comments=comments, new_branch=new_branch)
|
||||
>>> base = branch.base
|
||||
>>> head = branch.head
|
||||
>>> 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'
|
||||
>>> title = "feat: modify http lib",
|
||||
>>> body = "Change HTTP library used to send requests"
|
||||
>>> pr = await git_create_pull(
|
||||
>>> base_repo_name=repo_name,
|
||||
>>> base=base,
|
||||
>>> head=head,
|
||||
>>> title=title,
|
||||
>>> body=body,
|
||||
>>> access_token=access_token,
|
||||
>>> )
|
||||
>>> if isinstance(pr, PullRequest):
|
||||
>>> print(pr)
|
||||
PullRequest("feat: modify http lib")
|
||||
>>> if isinstance(pr, str):
|
||||
>>> print(f"Visit this url to create a new pull request: '{pr}'")
|
||||
Visit this url to create a new pull request: 'https://github.com/iorisa/snake-game/compare/master...feature/new'
|
||||
|
||||
>>> # create pull request
|
||||
>>> base_repo_name = "geekan/MetaGPT"
|
||||
>>> head_repo_name = "ioris/MetaGPT"
|
||||
|
|
@ -120,8 +92,7 @@ async def git_create_pull(
|
|||
>>> head = "feature/http"
|
||||
>>> title = "feat: modify http lib",
|
||||
>>> body = "Change HTTP library used to send requests"
|
||||
>>> from metagpt.tools.libs import get_env
|
||||
>>> access_token = await get_env(key="access_token", app_name="github")
|
||||
>>> app_name = "github"
|
||||
>>> pr = await git_create_pull(
|
||||
>>> base_repo_name=base_repo_name,
|
||||
>>> head_repo_name=head_repo_name,
|
||||
|
|
@ -129,7 +100,7 @@ async def git_create_pull(
|
|||
>>> head=head,
|
||||
>>> title=title,
|
||||
>>> body=body,
|
||||
>>> access_token=access_token,
|
||||
>>> app_name=app_name,
|
||||
>>> )
|
||||
>>> if isinstance(pr, PullRequest):
|
||||
>>> print(pr)
|
||||
|
|
@ -141,8 +112,11 @@ async def git_create_pull(
|
|||
Returns:
|
||||
PullRequest: The created pull request.
|
||||
"""
|
||||
|
||||
from metagpt.tools.libs import get_env
|
||||
from metagpt.utils.git_repository import GitRepository
|
||||
|
||||
access_token = await get_env(key="access_token", app_name=app_name)
|
||||
return await GitRepository.create_pull(
|
||||
base=base,
|
||||
head=head,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue