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

Linter tools #50

Merged
merged 10 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 10 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ on:
branches:
- main

# If another push to the same PR or branch happens while this workflow is still running,
# cancel the earlier run in favor of the next run.
#
# There's no point in testing an outdated version of the code. GitHub only allows
# a limited number of job runners to be active at the same time, so it's better to cancel
# pointless jobs early so that more useful jobs can run sooner.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
strategy:
Expand Down
14 changes: 10 additions & 4 deletions .github/workflows/integration_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ on:
branches:
- main

# If another push to the same PR or branch happens while this workflow is still running,
# cancel the earlier run in favor of the next run.
#
# There's no point in testing an outdated version of the code. GitHub only allows
# a limited number of job runners to be active at the same time, so it's better to cancel
# pointless jobs early so that more useful jobs can run sooner.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
strategy:
Expand Down Expand Up @@ -41,10 +51,6 @@ jobs:
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root

- name: Install project
run: poetry install --no-interaction --all-extras

- name: Run integration tests
Expand Down
14 changes: 10 additions & 4 deletions .github/workflows/integration_test_minimal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ on:
branches:
- main

# If another push to the same PR or branch happens while this workflow is still running,
# cancel the earlier run in favor of the next run.
#
# There's no point in testing an outdated version of the code. GitHub only allows
# a limited number of job runners to be active at the same time, so it's better to cancel
# pointless jobs early so that more useful jobs can run sooner.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
strategy:
Expand Down Expand Up @@ -41,10 +51,6 @@ jobs:
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root

- name: Install project
run: poetry install --no-interaction

- name: Run integration tests
Expand Down
4 changes: 0 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ jobs:
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root

- name: Install project
run: poetry install --no-interaction

- name: Run tests
Expand Down
16 changes: 11 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ on:
branches:
- main

# If another push to the same PR or branch happens while this workflow is still running,
# cancel the earlier run in favor of the next run.
#
# There's no point in testing an outdated version of the code. GitHub only allows
# a limited number of job runners to be active at the same time, so it's better to cancel
# pointless jobs early so that more useful jobs can run sooner.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
strategy:
Expand Down Expand Up @@ -41,11 +51,7 @@ jobs:
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root

- name: Install project
run: poetry install --no-interaction --extras "crewai llama-index"
run: poetry install --no-interaction --all-extras --with dev

- name: Run tests
run: poetry run pytest
Expand Down
4 changes: 2 additions & 2 deletions examples/aider_code_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

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


logger.setLevel(logging.INFO)
Expand Down
5 changes: 4 additions & 1 deletion motleycrew/common/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ class Defaults:
"crewai": "pip install crewai",
"llama_index": "pip install llama-index",
"autogen": "pip install pyautogen",
"lunary": "pip install lunary"
"lunary": "pip install lunary",
"aider": "pip install aider-chat",
"pglast": "pip install pglast",
}

DEFAULT_NUM_THREADS = 4
DEFAULT_EVENT_LOOP_SLEEP = 1
4 changes: 3 additions & 1 deletion motleycrew/tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from .tool import MotleyTool

from .autogen_chat_tool import AutoGenChatTool
from motleycrew.tools.image.dall_e import DallEImageGeneratorTool
from .image.dall_e import DallEImageGeneratorTool
from .llm_tool import LLMTool
from .mermaid_evaluator_tool import MermaidEvaluatorTool
from .python_repl import PythonREPLTool
from .code.postgresql_linter import PostgreSQLLinterTool
from .code.python_linter import PythonLinterTool
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, model: str = None, **kwargs):
model (str): model name
**kwargs:
"""
ensure_module_is_installed("aider", "pip install aider-chat")
ensure_module_is_installed("aider")

model = model or Defaults.DEFAULT_LLM_NAME
llm_model = Model(model=model)
Expand All @@ -44,7 +44,7 @@ class AiderToolInput(BaseModel):


def create_aider_tool(coder: Coder):
"""Create langchain tool from Aider coder.run() method
"""Create langchain tool from Aider Coder.run() method

Returns:
Tool:
Expand Down
55 changes: 55 additions & 0 deletions motleycrew/tools/code/postgresql_linter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from langchain_core.tools import Tool
from langchain_core.pydantic_v1 import BaseModel, Field

try:
from pglast import parse_sql, prettify
from pglast.parser import ParseError
except ImportError:
parse_sql = None
prettify = None
ParseError = None

from motleycrew.tools import MotleyTool
from motleycrew.common.utils import ensure_module_is_installed


class PostgreSQLLinterTool(MotleyTool):

def __init__(self):
"""PostgreSQL code verification tool
"""
ensure_module_is_installed("pglast")

langchain_tool = create_pgsql_linter_tool()
super().__init__(langchain_tool)


class PostgreSQLLinterInput(BaseModel):
"""Input for the PostgreSQLLinterTool.

Attributes:
query (str):
"""

query: str = Field(description="SQL code for validation")


def create_pgsql_linter_tool() -> Tool:
"""Create the underlying langchain tool for PostgreSQLLinterTool

Returns:
Tool:
"""
def parse_func(query: str) -> str:
try:
parse_sql(query)
return prettify(query)
except ParseError as e:
return str(e)

return Tool.from_function(
func=parse_func,
name="PostgreSQL linter tool",
description="Tool for validating PostgreSQL code",
args_schema=PostgreSQLLinterInput,
)
67 changes: 67 additions & 0 deletions motleycrew/tools/code/python_linter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import os
from typing import Union

from langchain_core.tools import StructuredTool
from langchain_core.pydantic_v1 import BaseModel, Field

from motleycrew.common.utils import ensure_module_is_installed
from motleycrew.tools import MotleyTool

Linter = None


class PythonLinterTool(MotleyTool):

def __init__(self):
"""Python code verification tool
"""
ensure_module_is_installed("aider")

langchain_tool = create_python_linter_tool()
super().__init__(langchain_tool)


class PythonLinterInput(BaseModel):
"""Input for the PythonLinterTool.

Attributes:
code (str):
file_name (str):
"""

code: str = Field(description="Python code for linting")
file_name: str = Field(description="file name for the code", default="code.py")


def create_python_linter_tool() -> StructuredTool:
"""Create the underlying langchain tool for PythonLinterTool

Returns:
Tool:
"""

def lint(code: str, file_name: str = None) -> Union[str, None]:
# create temp python file
temp_file_name = file_name or "code.py"
_, file_ext = os.path.splitext(temp_file_name)
if file_ext != ".py":
raise ValueError("The file extension must be .py")

with open(temp_file_name, 'w') as f:
f.write(code)

# lint code
try:
linter = Linter()
return linter.lint(temp_file_name)
except Exception as e:
return str(e)
finally:
os.remove(temp_file_name)

return StructuredTool.from_function(
func=lint,
name="python linter tool",
description="Tool for validating Python code",
args_schema=PythonLinterInput,
)
2 changes: 1 addition & 1 deletion motleycrew/tools/tool.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
""" Module description """

from typing import Union, Annotated, Optional, Dict, Any
from typing import Union, Optional, Dict, Any
from typing import Callable

from langchain.tools import BaseTool
Expand Down
Loading
Loading