Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aider code generation tool #38

Merged
merged 8 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions examples/aider_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from pathlib import Path
import os
import sys

from dotenv import load_dotenv

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 enable_cache, disable_cache, logger
from motleycrew.tools.aider_tool import AiderTool
import logging

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
# cd ../../
# git clone https://github.com/ShoggothAI/motleycrew-code-generation-example.git


def main():
crew = MotleyCrew(async_backend=AsyncBackend.THREADING)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove async backend here


git_dname = r"../../motleycrew-code-generation-example" # aider coder git dir name
sys.path.insert(0, os.path.abspath(git_dname))

check_functions_file = os.path.join(git_dname, "math_functions.py")
unit_tests_file = os.path.join(git_dname, "test_math_functions.py")
fnames = [unit_tests_file, check_functions_file]

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

researcher = CrewAIMotleyAgent(
role="Software Engineer",
goal="Writing unit tests",
backstory="""You are a leading software engineer working in the field of computer technology""",
delegation=False,
verbose=True,
tools=[aider_tool, shell_tool],
)

# Create tasks for your agent
create_unit_tests_task = SimpleTask(
crew=crew,
name="Adding a unit test",
description=f"""Generate unit tests for the module math_functions.py
Using py test, you can also add checks for possible exceptions and comments to the tests.""",
agent=researcher,
)

run_unit_tests_task = SimpleTask(
crew=crew,
name="Running unit tests",
description=f"""Run unit tests from the {unit_tests_file} file, using pytest
from the current directory and return the execution results""",
agent=researcher
)

create_unit_tests_task >> run_unit_tests_task

result = crew.run()

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


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

try:
from aider.coders import Coder
from aider.models import Model
except ImportError:
ensure_module_is_installed("aider-chat", "poetry run pip install aider-chat")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why poetry here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, let's put this inside AiderTool init in case we want to import this module in some init.py


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):

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 REPL tool.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Input for the REPL tool.
"""Input for the Aider tool.


Attributes:
with_message (str):
"""

with_message: str = Field(description="instructions for code generate")
Copy link
Contributor

@whimo whimo Jun 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with_message: str = Field(description="instructions for code generate")
with_message: str = Field(description="Instructions for code generation")



def create_aider_tool(coder: Coder):
""" Create langchain tool from aider coder

Returns:
Tool:
"""
return Tool.from_function(
func=coder.run,
name="aider tool",
description="Tool for generate programming code",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description="Tool for generate programming code",
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,
)
Loading