Skip to content

Commit

Permalink
Merge pull request #176 from ComposioHQ/kaavee/swe-update
Browse files Browse the repository at this point in the history
swe behavior changes
  • Loading branch information
kaavee315 committed Jun 19, 2024
2 parents bd98bc6 + 66a3af4 commit 6ca8c20
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 50 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ temp
.test_results
.trunk
refactor_debug.ipynb

**/coder_agent_logs_*
**/.composio.coder.*
3 changes: 2 additions & 1 deletion coders/composio_coders/benchmark/run_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ def build_issue_description(hints, problem_statement):
tmpl = ""
if hints:
tmpl = f"Here are few hints to solve the issue described in problem_statement {hints}"

tmpl += f"""\n\n
Here is the issue, that you have to solve all ob your own
Here is the issue, that you have to solve all on your own
{problem_statement}
"""
return tmpl
Expand Down
126 changes: 90 additions & 36 deletions coders/composio_coders/swe.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime
import json
import logging
import os
from pathlib import Path
from typing import Any, Dict, List

Expand All @@ -13,43 +14,47 @@
MODEL_ENV_AZURE,
MODEL_ENV_OPENAI,
)
from composio_crewai import App, ComposioToolSet
from crewai import Agent, Task
from composio_crewai import Action, App, ComposioToolSet
from crewai import Agent, Crew, Task
from langchain_openai import AzureChatOpenAI, ChatOpenAI
from pydantic import BaseModel, Field
from rich.logging import RichHandler

from composio import Composio
from composio.local_tools.local_workspace.workspace.actions.create_workspace import (
CreateWorkspaceResponse,
)


AGENT_BACKSTORY_TMPL = """
You are an autonomous programmer, your task is to solve the issue given in task with the tools in hand.
Your mentor gave you following tips.
1. Always start by initializing the workspace.
2. Use the workspace_id returned to use tools to run commands. The commands are run on shell.
3. use clone the git repo {repo_name} from the base_commit {base_commit} in workspace
4. After setting up environment - *Always start with try to replicate the bug that the issues discusses*.
If the issue includes code for reproducing the bug, we recommend that you re-implement that in your environment,
and run it to make sure you can reproduce the bug.
1. A workspace is initialized for you, and you will be working on workspace, where workspace_id is: {workspace_id}. The git repo is cloned in
the path {repo_name_dir}, you need to work in this directory.
2. PLEASE READ THE CODE AND UNDERSTAND THE FILE STRUCTURE OF THE CODEBASE USING GIT REPO TREE ACTION.
3. POST THAT READ ALL THE RELEVANT READMEs AND TRY TO LOOK AT THE FILES RELATED TO THE ISSUE.
4. Form a thesis around the issue and the codebase.
5. THEN TRY TO REPLICATE THE BUG THAT THE ISSUES DISCUSSES.
If the issue includes code for reproducing the bug, we recommend that you re-implement that in your environment, and run it to make sure you can reproduce the bug.
Then start trying to fix it.
When you think you've fixed the bug, re-run the bug reproduction script to make sure that the bug has indeed been fixed.
If the bug reproduction script does not print anything when it successfully runs,
we recommend adding a print("Script completed successfully, no errors.") command at the end of the file,
so that you can be sure that the script indeed ran fine all the way through.
5. If you run a command and it doesn't work, try running a different command. A command that did not work once
will not work the second time unless you modify it!
6. If you open a file and need to get to an area around a specific line that is not in the first 100 lines,
say line 583, don't just use the scroll_down command multiple times. Instead, use the goto 583 command. It's much quicker.
7. If the bug reproduction script requires inputting/reading a specific file, such as buggy-input.png, and you'd like
to understand how to input that file, conduct a search in the existing repo code, to see whether someone else has already done that.
Do this by running the command: find_file "buggy-input.png" If that doesn't work, use the linux 'find' command.
8. Always make sure to look at the currently open file and the current working directory (which appears right after the currently open file).
The currently open file might be in a different directory than the working directory! Note that some commands,
such as 'create', open files, so they might change the current open file.
9. When editing files, it is easy to accidentally specify a wrong line number or to write code with incorrect indentation.
Always check the code after you issue an edit to make sure that it reflects what you wanted to accomplish.
If it didn't, issue another command to fix it.
10. When you finish working on the issue, use submit patch tool to submit your patch.
6. If you run a command and it doesn't work, try running a different command. A command that did not work once will not work the second time unless you modify it!
7. If you open a file and need to get to an area around a specific line that is not in the first 100 lines, say line 583,
don't just use the scroll_down command multiple times. Instead, use the goto 583 command. It's much quicker.
8. If the bug reproduction script requires inputting/reading a specific file, such as buggy-input.png, and you'd like
to understand how to input that file, conduct a search in the existing repo code, to see whether someone else has already done that.
Do this by running the command: find_file "buggy-input.png" If that doesn't work, use the linux 'find' command.
9. Always make sure to look at the currently open file and the current working directory (which appears right after the currently open file).
The currently open file might be in a different directory than the working directory! Note that some commands, such as 'create', open files,
so they might change the current open file.
10. When editing files, it is easy to accidentally specify a wrong line number or to write code with incorrect indentation.
Always check the code after you issue an edit to make sure that it reflects what you wanted to accomplish. If it didn't, issue another
command to fix it.
11. When you finish working on the issue, use submit patch tool to submit your patch.
12. SUBMIT THE PATCH TO THE REVIEWER AGENT AGAIN AND ASK THEM TO REVIEW THE PATCH AND SUBMIT IT ONLY IF THEY APPROVE IT.
"""
ISSUE_DESC_TMPL = """
We're currently solving the following issue within our repository. Here's the issue text:
Expand Down Expand Up @@ -127,14 +132,18 @@ def __init__(self, args: CoderAgentArgs):
App.LOCALWORKSPACE,
App.CMDMANAGERTOOL,
App.HISTORYKEEPER,
App.SUBMITPATCHTOOL,
]
)
composio_client = Composio()
self.entity = composio_client.get_entity("swe-agent")
# initialize composio client
self.composio_entity = self.get_composio_entity()

# initialize agent-related different prompts
self.agent_role = self.args.agent_role
self.agent_goal = self.args.agent_goal
self.expected_output = self.args.task_expected_output
self.agent_role = "You are the best programmer. You think carefully and step by step take action."
self.agent_goal = "Help fix the given issue / bug in the code. And make sure you get it working. Ask the reviewer agent to review the patch and submit it once they approve it."
self.expected_output = "A patch should be generated which fixes the given issue"
self.agent_backstory_tmpl = args.agent_backstory_tmpl
self.issue_description_tmpl = args.issue_description_tmpl
# initialize logger
Expand Down Expand Up @@ -189,11 +198,13 @@ def add_in_logs(self, step_output):
def get_llm(self):
model_env = self.model_env.get(KEY_MODEL_ENV)
if model_env == MODEL_ENV_OPENAI:
openai_key = self.model_env.get(KEY_API_KEY)
openai_key = os.environ.get(("OPANAI_API_KEY"))
return ChatOpenAI(model="gpt-4-turbo", api_key=openai_key)
if model_env == MODEL_ENV_AZURE:
azure_endpoint = self.model_env.get(KEY_AZURE_ENDPOINT)
azure_key = self.model_env.get(KEY_API_KEY)
os.environ["AZURE_OPENAI_API_KEY"] = self.model_env[KEY_AZURE_ENDPOINT]
os.environ["AZURE_OPENAI_API_KEY"] = self.model_env[KEY_API_KEY]
azure_llm = AzureChatOpenAI(
azure_endpoint=azure_endpoint,
api_key=azure_key,
Expand All @@ -207,21 +218,29 @@ def get_llm(self):
def run(self):
llm = self.get_llm()

self.logger.info(
"starting agent for issue-id: %s\n"
"issue-description: %s\n"
"repo_name: %s\n",
self.issue_config.issue_id,
self.issue_config.issue_desc,
self.issue_config.issue_desc,
workspace_create_resp: CreateWorkspaceResponse = self.entity.execute(
Action.LOCALWORKSPACE_CREATEWORKSPACEACTION, {}
)
workspace_id = workspace_create_resp.workspace_id
logger.info("workspace is created, workspace-id is: %s", workspace_id)
git_clone_response = self.entity.execute(
Action.CMDMANAGERTOOL_GITHUBCLONECMD,
params={
"workspace_id": workspace_id,
"repo_name": self.issue_config.repo_name,
},
)

issue_added_instruction = self.issue_description_tmpl.format(
issue=self.issue_config.issue_desc, issue_id=self.issue_config.issue_id
)
backstory_added_instruction = self.agent_backstory_tmpl.format(
repo_name=self.repo_name, base_commit=self.issue_config.base_commit_id
workspace_id=workspace_id,
repo_name=self.repo_name,
repo_name_dir="/" + self.repo_name.split("/")[-1].strip(),
base_commit=self.issue_config.base_commit_id,
)
logger.info("git clone response: %s", git_clone_response)

swe_agent = Agent(
role=self.agent_role,
goal=self.agent_goal,
Expand All @@ -239,7 +258,41 @@ def run(self):
agent=swe_agent,
expected_output=self.expected_output,
)
coding_task.execute()

reviewer_agent = Agent(
role="You are the best reviewer. You think carefully and step by step take action.",
goal="Review the patch and make sure it fixes the issue.",
backstory="An AI Agent tries to solve an issue and submits a patch to the repo. "
"You can assume the AI agent operates as a junior developer and has limited knowledge of the codebase."
"It's your job to review the patch and make sure it fixes the issue."
"The patch might be incomplete. In that case point out the missing parts and ask the AI agent to add them."
"The patch might have some compilation issues/typo. Point out those and ask the AI agent to fix them."
"The patch might have some logical issues. Point out those and ask the AI agent to fix them."
"Once the patch is ready, approve it and ask the AI agent to submit it."
"It is fine to have multiple iterations of the review. Keep iterating until the patch is ready to be submitted."
"The are the best reviewer. You think carefully and step by step take action.",
verbose=True,
llm=llm,
tools=self.composio_toolset,
memory=True,
step_callback=self.add_in_logs,
allow_delegation=True,
)

review_task = Task(
description="Review the patch and make sure it fixes the issue.",
agent=reviewer_agent,
context=[coding_task],
expected_output="The patch is ready to be submitted to the repo.",
)

crew = Crew(
agents=[swe_agent, reviewer_agent],
tasks=[coding_task, review_task],
memory=True,
)

crew.kickoff()
self.save_history(self.issue_config.issue_id)


Expand Down Expand Up @@ -268,4 +321,5 @@ def run(self):
model_env_config=ctx.model_env,
)
c_agent = CoderAgent(args)

c_agent.run()
6 changes: 6 additions & 0 deletions composio/client/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -13830,6 +13830,12 @@ def from_app_and_action(cls, app: str, name: str) -> "Action":
True,
True,
)
CMDMANAGERTOOL_GITREPOTREE = (
"cmdmanagertool",
"cmdmanagertool_gitrepotree",
True,
True,
)
CMDMANAGERTOOL_EDITFILE = ("cmdmanagertool", "cmdmanagertool_editfile", True, True)
CMDMANAGERTOOL_RUNCOMMANDONWORKSPACE = (
"cmdmanagertool",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import typing as t
from abc import ABC, abstractmethod
from pathlib import Path
from typing import Optional

from pydantic import BaseModel, Field

Expand Down Expand Up @@ -33,7 +33,10 @@ class BaseRequest(BaseModel):


class BaseResponse(BaseModel):
output: str = Field(..., description="output of the command")
class Config:
arbitrary_types_allowed = True

output: t.Any = Field(..., description="output of the command")
return_code: int = Field(
..., description="Any output or errors that occurred during the file edit."
)
Expand All @@ -50,8 +53,8 @@ class BaseAction(Action[BaseRequest, BaseResponse], ABC):
_tool_name = "cmdmanagertool"
script_file = ""
command = ""
workspace_factory: Optional[WorkspaceManagerFactory] = None
history_processor: Optional[HistoryProcessor] = None
workspace_factory: t.Optional[WorkspaceManagerFactory] = None
history_processor: t.Optional[HistoryProcessor] = None

def __init__(self):
super().__init__()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class GithubCloneResponse(BaseResponse):

class GithubCloneCmd(BaseAction):
"""
Clones a github repository
Clones a github repository at a given commit-id.
"""

_history_maintains: bool = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

class GitRepoTree(BaseAction):
"""
generate a tree of the repository. This command lists all files in the current commit across all directories.
Generate a tree of the repository. This command lists all files in the current commit across all directories.
Returns a list of files with their relative paths in the codebase.
It is useful to understand the file structure of the codebase and to find the relevant files for a given issue.
The command writes the result to a file in current directory. Read the file 'git_repo_tree.txt' for getting the
git-repo-tree results
"""

_display_name = "Git repo tree action"
Expand All @@ -29,16 +33,16 @@ def execute(
) -> BaseResponse:
self._setup(request_data)
self.script_file = SCRIPT_EDIT_LINTING
self.command = "git ls-tree -r HEAD"

self.command = "git ls-tree -r HEAD --name-only > ./git_repo_tree.txt"
if self.container_process is None:
raise ValueError("Container process is not set")

output, return_code = communicate(
self.container_process, self.container_obj, self.command, self.parent_pids
)
output, return_code = process_output(output, return_code)
files = output.split("\n")
return BaseResponse(
output=output,
output=files,
return_code=return_code,
)
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ScrollResponse(BaseResponse):

class Scroll(BaseAction):
"""
Scrolls the view within a shell session down by 100 lines
Scrolls the view within a shell session down by 100 lines.
"""

_display_name = "Scroll Action"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class GetCurrentDirResponse(BaseResponse):

class GetCurrentDirCmd(BaseAction):
"""
Gets the current directory.
Gets the current directory. This is equivalent to running 'pwd' in the terminal.
"""

_display_name = "Get Current Directory Action"
Expand Down
2 changes: 2 additions & 0 deletions composio/local_tools/local_workspace/cmd_manager/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
EditFile,
FindFileCmd,
GetCurrentDirCmd,
GitRepoTree,
GithubCloneCmd,
GoToLineNumInOpenFile,
OpenFile,
Expand Down Expand Up @@ -41,6 +42,7 @@ def actions(self) -> list:
RunCommandOnWorkspace,
GetCurrentDirCmd,
GithubCloneCmd,
GitRepoTree,
]

def triggers(self) -> list:
Expand Down
1 change: 1 addition & 0 deletions composio/storage/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""
Composio user account storage helpers.
"""

from .base import LocalStorage
1 change: 0 additions & 1 deletion tests/test_cli/test_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Test connections command group.
"""


from tests.test_cli.base import BaseCliTest


Expand Down

0 comments on commit 6ca8c20

Please sign in to comment.