Skip to content

Commit

Permalink
Aider code generation tool (#38)
Browse files Browse the repository at this point in the history
* add AiderTool

* add aider example

* add ImportError handling for the aider-chat package

* remove AiderTool from tools init

* update aider_example with launch of a single task

* update AiderTool description

* update aider_example for sync run

* Minor improvements for Aider demo

---------

Co-authored-by: User <[email protected]>
Co-authored-by: whimo <[email protected]>
  • Loading branch information
3 people committed Jun 7, 2024
1 parent 5b256f4 commit e678da2
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
75 changes: 75 additions & 0 deletions examples/aider_code_generation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from pathlib import Path
import os
import sys

from dotenv import load_dotenv
import logging


from langchain_community.tools import ShellTool
from motleycrew.agents.crewai import CrewAIMotleyAgent
from motleycrew.common import configure_logging, AsyncBackend
from motleycrew.tasks import SimpleTask
from motleycache import logger
from motleycrew.tools.aider_tool import AiderTool


logger.setLevel(logging.INFO)
WORKING_DIR = Path(os.path.realpath("."))

try:
from motleycrew import MotleyCrew
except ImportError:
# if we are running this from source
motleycrew_location = os.path.realpath(WORKING_DIR / "..")
sys.path.append(motleycrew_location)


# run instruction
# to run the example, you need to clone the repository for the example at the same level as your project
# cd ../../
# git clone https://github.com/ShoggothAI/motleycrew-code-generation-example.git


def main():
crew = MotleyCrew()

git_repo_path = r"../../motleycrew-code-generation-example" # cloned repository path
tests_file = os.path.join(git_repo_path, "test_math_functions.py")
target_files = [tests_file]

aider_tool = AiderTool(fnames=target_files, git_dname=git_repo_path, auto_commits=False)
shell_tool = ShellTool()

developer = CrewAIMotleyAgent(
role="Software Engineer",
goal="Writing unit tests",
backstory="You are a lead software engineer working in a big tech company.",
delegation=False,
verbose=True,
tools=[aider_tool, shell_tool],
)

create_unit_tests_task = SimpleTask(
crew=crew,
name="Adding a unit test",
description=f"Generate unit tests for the module math_functions.py using pytest. "
f"You should also add test cases for possible exceptions "
f"and write comments to the tests. You should also use test parameterization. "
f"After go to the directory {git_repo_path} and run created unit tests. "
f"If the tests were executed successfully, return the result of execution, "
f"if not, rewrite the tests and rerun them until they are working.",
agent=developer,
)

result = crew.run()

# Get the outputs of the task
print(create_unit_tests_task.output)
return create_unit_tests_task.output


if __name__ == "__main__":
configure_logging(verbose=True)
load_dotenv()
main()
59 changes: 59 additions & 0 deletions motleycrew/tools/aider_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from motleycrew.common.utils import ensure_module_is_installed

try:
from aider.coders import Coder
from aider.models import Model
except ImportError:
Coder = None
Model = None

from langchain.tools import Tool
from langchain_core.pydantic_v1 import BaseModel, Field

from motleycrew.common import Defaults
from motleycrew.tools import MotleyTool


class AiderTool(MotleyTool):

def __init__(self, model: str = None, **kwargs):
"""Tool for code generation using Aider.
Args:
model (str): model name
**kwargs:
"""
ensure_module_is_installed("aider", "pip install aider-chat")

model = model or Defaults.DEFAULT_LLM_NAME
llm_model = Model(model=model)
coder = Coder.create(main_model=llm_model, **kwargs)

langchain_tool = create_aider_tool(coder)
super(AiderTool, self).__init__(langchain_tool)


class AiderToolInput(BaseModel):
"""Input for the Aider tool.
Attributes:
with_message (str):
"""

with_message: str = Field(description="instructions for code generation")


def create_aider_tool(coder: Coder):
"""Create langchain tool from Aider coder.run() method
Returns:
Tool:
"""
return Tool.from_function(
func=coder.run,
name="aider tool",
description="Tool for code generation that has access to the provided repository. "
"Ask it to make changes in the code: fix bugs, add features, write tests etc. "
"It doesn't run the code by itself.",
args_schema=AiderToolInput,
)

0 comments on commit e678da2

Please sign in to comment.