From 9e11a558f28452d12b6db0f82ce0185ab2569e17 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 10:33:35 -0700 Subject: [PATCH 01/36] Removed logtail source key --- sweepai/config/server.py | 2 -- sweepai/handlers/on_comment.py | 4 ---- sweepai/handlers/on_ticket.py | 40 ---------------------------------- 3 files changed, 46 deletions(-) diff --git a/sweepai/config/server.py b/sweepai/config/server.py index c3080389de..0b09e60eb6 100644 --- a/sweepai/config/server.py +++ b/sweepai/config/server.py @@ -140,8 +140,6 @@ "POSTHOG_API_KEY", "phc_CnzwIB0W548wN4wEGeRuxXqidOlEUH2AcyV2sKTku8n" ) -LOGTAIL_SOURCE_KEY = os.environ.get("LOGTAIL_SOURCE_KEY") - E2B_API_KEY = os.environ.get("E2B_API_KEY") SUPPORT_COUNTRY = os.environ.get("GDRP_LIST", "").split(",") diff --git a/sweepai/handlers/on_comment.py b/sweepai/handlers/on_comment.py index 7abb7e6a39..c5e4e142b2 100644 --- a/sweepai/handlers/on_comment.py +++ b/sweepai/handlers/on_comment.py @@ -7,7 +7,6 @@ import traceback from typing import Any -from logtail import LogtailHandler from loguru import logger from tabulate import tabulate @@ -17,7 +16,6 @@ DEFAULT_GPT35_MODEL, ENV, GITHUB_BOT_USERNAME, - LOGTAIL_SOURCE_KEY, MONGODB_URI, ) from sweepai.core.context_pruning import get_relevant_context @@ -60,8 +58,6 @@ def on_comment( with logger.contextualize( tracking_id=tracking_id, ): - handler = LogtailHandler(source_token=LOGTAIL_SOURCE_KEY) - logger.add(handler) logger.info( f"Calling on_comment() with the following arguments: {comment}," f" {repo_full_name}, {repo_description}, {pr_path}" diff --git a/sweepai/handlers/on_ticket.py b/sweepai/handlers/on_ticket.py index 742dbad5fe..b48316df40 100644 --- a/sweepai/handlers/on_ticket.py +++ b/sweepai/handlers/on_ticket.py @@ -20,7 +20,6 @@ from github import BadCredentialsException, Github, Repository from github.Issue import Issue from github.PullRequest import PullRequest as GithubPullRequest -from logtail import LogtailContext, LogtailHandler from loguru import logger from tabulate import tabulate from tqdm import tqdm @@ -45,7 +44,6 @@ ENV, GITHUB_LABEL_NAME, IS_SELF_HOSTED, - LOGTAIL_SOURCE_KEY, MONGODB_URI, OPENAI_USE_3_5_MODEL_ONLY, PROGRESS_BASE_URL, @@ -171,33 +169,6 @@ """ -def initialize_logtail_context( - title: str, - issue_url: int, - issue_number: str, - repo_full_name: str, - repo_description: str, - username: str, - comment_id: int = None, - edited: bool = False, -): - context = LogtailContext() - context.context( - task={ - "issue_url": issue_url, - "issue_number": issue_number, - "repo_full_name": repo_full_name, - "repo_description": repo_description, - "username": username, - "comment_id": comment_id, - "edited": edited, - "issue_title": title, - } - ) - handler = LogtailHandler(source_token=LOGTAIL_SOURCE_KEY, context=context) - logger.add(handler) - - # Add :eyes: emoji to ticket def add_emoji(issue: Issue, comment_id: int = None, reaction_content="eyes"): item_to_react_to = issue.get_comment(comment_id) if comment_id else issue @@ -464,17 +435,6 @@ def on_ticket( lint_mode, ) = strip_sweep(title) - fire_and_forget_wrapper(initialize_logtail_context)( - title, - issue_url, - issue_number, - repo_full_name, - repo_description, - username, - comment_id, - edited, - ) - summary = summary or "" summary = re.sub( "
(\r)?\nChecklist.*", From c9795ac7a14bccdf1cb76f9024dc7f5fa01f7f87 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 10:33:45 -0700 Subject: [PATCH 02/36] Refactored function --- sweepai/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sweepai/api.py b/sweepai/api.py index c003d954c2..aba212ccff 100644 --- a/sweepai/api.py +++ b/sweepai/api.py @@ -299,7 +299,7 @@ def run(self, context: Context): request_dict = event_payload.get("request") event = event_payload.get("event") - run(request_dict, event) + handle_event(request_dict, event) workflow = OnGithubEvent() worker.register_workflow(workflow) @@ -322,7 +322,7 @@ def handle_github_webhook(event_payload): # if hatchet: # hatchet.client.event.push("github:webhook", event_payload) # else: - run(event_payload.get("request"), event_payload.get("event")) + handle_event(event_payload.get("request"), event_payload.get("event")) def handle_request(request_dict, event=None): @@ -420,7 +420,7 @@ def update_sweep_prs_v2(repo_full_name: str, installation_id: int): logger.warning("Failed to update sweep PRs") -def run(request_dict, event): +def handle_event(request_dict, event): action = request_dict.get("action") if repo_full_name := request_dict.get("repository", {}).get("full_name"): From d10e2c7442da62a50391b3f72588e764f007d18c Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 10:34:13 -0700 Subject: [PATCH 03/36] Added TODO --- sweepai/core/vector_db.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sweepai/core/vector_db.py b/sweepai/core/vector_db.py index ded3212a3e..a852a69471 100644 --- a/sweepai/core/vector_db.py +++ b/sweepai/core/vector_db.py @@ -37,7 +37,7 @@ raise ValueError(f"Invalid OPENAI_API_TYPE: {OPENAI_API_TYPE}") CACHE_VERSION = "v1.3.04" -redis_client: Redis = Redis.from_url(REDIS_URL) +redis_client: Redis = Redis.from_url(REDIS_URL) # TODO: add lazy loading tiktoken_client = Tiktoken() @@ -86,7 +86,13 @@ def embed_text_array(texts: tuple[str]) -> list[np.ndarray]: texts = [text if text else " " for text in texts] batches = [texts[i : i + BATCH_SIZE] for i in range(0, len(texts), BATCH_SIZE)] with multiprocessing.Pool(processes=multiprocessing.cpu_count() // 4) as pool: - embeddings = list(tqdm(pool.imap(openai_with_expo_backoff, batches), total=len(batches), desc="openai embedding")) + embeddings = list( + tqdm( + pool.imap(openai_with_expo_backoff, batches), + total=len(batches), + desc="openai embedding", + ) + ) return embeddings From 902ade010494badb14ad92e6ab8b325744a20cb9 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 10:34:21 -0700 Subject: [PATCH 04/36] Cleaned up dependencies --- pyproject.toml | 245 +++++-------------------------------------------- 1 file changed, 24 insertions(+), 221 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9b96ad5994..31cc537281 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ Homepage = "https://sweep.dev" [project] name = "sweepai" -version = "1.0.8" +version = "1.0.10" description = "Sweep fixes GitHub issues" authors = [ {name = "Kevin Lu", email = "kevin@sweep.dev"}, @@ -31,231 +31,34 @@ classifiers = [ "Programming Language :: Python :: 3.10" ] dependencies = [ - "aiohttp==3.9.3", - "aiosignal==1.3.1", - "aiostream==0.5.2", - "altair==4.2.2", - "amqp==5.2.0", - "annotated-types==0.6.0", - "anyio==4.3.0", - "argon2-cffi==23.1.0", - "argon2-cffi-bindings==21.2.0", - "Arpeggio==2.0.2", - "arrow==1.3.0", - "asgiref==3.7.2", - "astroid==2.15.8", - "asttokens==2.4.1", - "async-lru==2.0.4", - "async-timeout==4.0.3", - "attrs==23.2.0", - "Babel==2.14.0", + "typer==0.9.0", + "pygithub==2.2.0", + "loguru==0.7.2", + "rich==13.7.1", + "fastapi==0.110.0", + "prometheus-fastapi-instrumentator==7.0.0", + "pyyaml==6.0.1", + "python-dotenv==1.0.1", + "openai==1.13.3", "backoff==2.2.1", - "beautifulsoup4==4.12.3", - "billiard==4.2.0", - "bleach==6.1.0", - "blinker==1.7.0", - "build==0.10.0", - "cachetools==5.3.2", - "caliper-reader==0.4.0", - "celery==5.3.6", - "certifi==2024.2.2", - "cffi==1.16.0", - "cfgv==3.4.0", - "charset-normalizer==3.3.2", - "click==8.1.7", - "click-didyoumean==0.3.0", - "click-plugins==1.1.1", - "click-repl==0.3.0", - "comm==0.2.1", - "config-path==1.0.5", - "contourpy==1.2.0", - "coverage==7.4.3", - "cryptography==42.0.5", - "cycler==0.12.1", - "debugpy==1.8.1", - "decorator==5.1.1", - "defusedxml==0.7.1", - "Deprecated==1.2.14", - "dill==0.3.8", - "distlib==0.3.8", - "distro==1.9.0", - "dnspython==2.6.1", - "entrypoints==0.4", - "eventlet==0.33.3", - "exceptiongroup==1.2.0", - "execnet==2.0.2", - "executing==2.0.1", - "fancycompleter==0.9.1", - "fastapi==0.109.2", - "fastjsonschema==2.19.1", - "filelock==3.13.1", - "flake8==6.1.0", - "fonttools==4.49.0", - "fqdn==1.5.1", - "frozenlist==1.4.1", - "gitdb==4.0.11", - "GitPython==3.1.42", - "greenlet==2.0.1", - "grpcio==1.62.0", - "grpcio-tools==1.62.0", - "grpclib==0.4.3", - "h11==0.14.0", - "h2==4.1.0", - "hatchet-sdk==0.15.4", - "hpack==4.0.0", - "httpcore==1.0.4", - "httpx==0.26.0", - "hyperframe==6.0.1", - "identify==2.5.35", - "idna==3.6", - "importlib-metadata==7.0.1", + "pymongo==4.6.2", + "gitpython==3.1.42", + "tree-sitter==0.21.0", + "tree-sitter-languages==1.10.2", + "rapidfuzz==3.6.2", "importmagic==0.1.7", - "iniconfig==2.0.0", - "isoduration==20.11.0", - "isort==5.13.2", - "jedi==0.19.1", - "Jinja2==3.1.3", - "json5==0.9.17", - "jsonpointer==2.4", - "jsonschema==4.21.1", - "jsonschema-specifications==2023.12.1", - "kiwisolver==1.4.5", - "kombu==5.3.5", - "lazy-object-proxy==1.10.0", - "llvmlite==0.42.0", - "logtail-python==0.2.10", - "loguru==0.7.2", - "lxml==4.9.3", - "Markdown==3.5.2", - "markdown-it-py==3.0.0", - "markdownify==0.11.6", - "MarkupSafe==2.1.5", - "mccabe==0.7.0", - "mdurl==0.1.2", - "mistune==3.0.2", - "monotonic==1.6", - "mpmath==1.3.0", - "msgpack==1.0.7", - "multidict==6.0.5", - "multiprocess==0.70.16", - "nest-asyncio==1.6.0", + "pyflakes==3.2.0", "networkx==3.2.1", - "nodeenv==1.8.0", - "notebook==7.1.0", - "notebook_shim==0.2.4", - "nptyping==2.5.0", + "attrs==23.2.0", + "redis==5.0.3", "numpy==1.26.4", - "openai==1.12.0", - "overrides==7.7.0", - "packaging==23.2", - "pandocfilters==1.5.1", - "parso==0.8.3", - "pathspec==0.12.1", - "pexpect==4.9.0", - "platformdirs==4.2.0", - "pluggy==1.4.0", - "posthog==3.4.2", - "pre-commit==3.6.2", - "prometheus-fastapi-instrumentator==6.1.0", - "prometheus_client==0.20.0", - "prompt-toolkit==3.0.43", - "protobuf==4.25.3", - "psutil==5.9.8", - "ptyprocess==0.7.0", - "pure-eval==0.2.2", - "py-spy==0.3.14", - "pyarrow==15.0.0", - "pycodestyle==2.11.1", - "pycparser==2.21", - "pycubexr==1.2.1", - "pydantic==2.6.3", - "pydantic_core==2.16.3", - "pydot==2.0.0", - "pyee==9.0.4", - "pyflakes==3.1.0", - "PyGithub==1.58.2", - "Pygments==2.17.2", - "PyJWT==2.8.0", - "pymongo==4.6.2", - "PyNaCl==1.5.0", - "pyparsing==3.1.1", - "pyproject_hooks==1.0.0", - "pyrepl==0.9.0", - "pytest==7.4.4", - "pytest-xdist==3.5.0", - "python-dateutil==2.9.0.post0", - "python-dotenv==1.0.1", - "python-json-logger==2.0.7", - "pytoolconfig==1.3.1", - "pytz==2024.1", - "PyYAML==6.0.1", - "pyzmq==25.1.2", - "qtconsole==5.5.1", - "QtPy==2.4.1", - "rapidfuzz==3.6.1", - "redis==5.0.1", - "referencing==0.33.0", - "regex==2023.12.25", - "replicate==0.15.4", - "requests==2.31.0", - "resend==0.6.0", - "rfc3339-validator==0.1.4", - "rfc3986-validator==0.1.1", - "rich==13.7.0", - "rope==1.12.0", - "rpds-py==0.18.0", - "ruff==0.3.0", - "Send2Trash==1.8.2", - "sigtools==4.0.1", - "six==1.16.0", - "smmap==5.0.1", - "sniffio==1.3.1", - "soupsieve==2.5", - "stack-data==0.6.3", - "starlette==0.36.3", - "streamlit==1.31.1", - "synchronicity==0.5.3", - "tabulate==0.9.0", - "tblib==3.0.0", - "tenacity==8.2.3", - "terminado==0.18.0", - "textX==4.0.1", - "tiktoken==0.3.3", - "tinycss2==1.2.1", - "toml==0.10.2", - "tomli==2.0.1", - "tomlkit==0.12.3", - "toolz==0.12.1", - "tornado==6.4", - "tqdm==4.66.2", - "traitlets==5.14.1", - "tree-sitter==0.20.4", - "tree-sitter-languages==1.10.2", - "typer==0.9.0", - "types-certifi==2021.10.8.3", - "types-python-dateutil==2.8.19.20240106", - "types-toml==0.10.8.7", - "typing_extensions==4.10.0", - "tzdata==2024.1", - "tzlocal==5.2", - "unidiff==0.7.5", - "uri-template==1.3.0", - "urllib3==2.2.1", - "validators==0.22.0", - "vine==5.1.0", - "virtualenv==20.25.1", - "watchdog==4.0.0", - "watchfiles==0.21.0", - "wcwidth==0.2.13", - "webcolors==1.13", - "webencodings==0.5.1", - "websocket-client==1.7.0", - "widgetsnbextension==4.0.10", - "wmctrl==0.5", - "wrapt==1.16.0", + "markdown==3.5.2", "yamllint==1.35.1", - "yarl==1.9.4", - "zipp==3.17.0", + "logtail==1.0.1", + "tabulate==0.9.0", + "resend==0.8.0", + "psutil==5.9.8", + "jinja2==3.1.3" ] [tool.isort] From c412ab8e1d7b19c74b308d46a3cfb71c39667cdc Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 11:11:37 -0700 Subject: [PATCH 05/36] Fixed pydantic error --- sweepai/utils/progress.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sweepai/utils/progress.py b/sweepai/utils/progress.py index 89df5ef6dc..033ecf3dc6 100644 --- a/sweepai/utils/progress.py +++ b/sweepai/utils/progress.py @@ -27,7 +27,7 @@ class AssistantAPIMessageRole(Enum): class AssistantAPIMessage(BaseModel): - model_config = ConfigDict(use_enum_values=True) + model_config = ConfigDict(use_enum_values=True, validate_default=True) role: AssistantAPIMessageRole content: str = "" @@ -44,7 +44,7 @@ class AssistantStatus(Enum): class AssistantConversation(BaseModel): - model_config = ConfigDict(use_enum_values=True) + model_config = ConfigDict(use_enum_values=True, validate_default=True) messages: list[AssistantAPIMessage] = [] is_active: bool = True status: AssistantStatus = "in_progress" @@ -188,7 +188,7 @@ class TicketProgressStatus(Enum): class SearchProgress(BaseModel): - model_config = ConfigDict(use_enum_values=True) + model_config = ConfigDict(use_enum_values=True, validate_default=True) indexing_progress: int = 0 indexing_total: int = 0 @@ -237,13 +237,13 @@ class TicketUserStateTypes(Enum): class TicketUserState(BaseModel): - model_config = ConfigDict(use_enum_values=True) + model_config = ConfigDict(use_enum_values=True, validate_default=True) state_type: TicketUserStateTypes = TicketUserStateTypes.RUNNING waiting_deadline: int = 0 class TicketProgress(BaseModel): - model_config = ConfigDict(use_enum_values=True) + model_config = ConfigDict(use_enum_values=True, validate_default=True) tracking_id: str username: str = "" context: TicketContext = TicketContext() @@ -275,9 +275,9 @@ def _save(self): try: if MONGODB_URI is None: return None - if self.dict() == self.prev_dict: + if self.model_dump() == self.prev_dict: return - current_dict = self.dict() + current_dict = self.model_dump() del current_dict["prev_dict"] self.prev_dict = current_dict db = global_mongo_client["progress"] @@ -353,8 +353,8 @@ def create_index(): # + " https://discord.gg/sweep." # ) # ticket_progress.status = TicketProgressStatus.ERROR - # ticket_progress.save() + ticket_progress.save() ticket_progress.wait() - # new_ticket_progress = TicketProgress.load("test") - # print(new_ticket_progress) + new_ticket_progress = TicketProgress.load("test") + print(new_ticket_progress) # assert new_ticket_progress == ticket_progress From 2b7e7fd50655107c78c986c8527a87d343800de5 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 12:14:58 -0700 Subject: [PATCH 06/36] Deps fixes --- pyproject.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 31cc537281..259b7ab8d9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ Homepage = "https://sweep.dev" [project] name = "sweepai" -version = "1.0.10" +version = "1.0.12" description = "Sweep fixes GitHub issues" authors = [ {name = "Kevin Lu", email = "kevin@sweep.dev"}, @@ -58,7 +58,9 @@ dependencies = [ "tabulate==0.9.0", "resend==0.8.0", "psutil==5.9.8", - "jinja2==3.1.3" + "jinja2==3.1.3", + "tiktoken==0.6.0", + "pylint==3.1.0" ] [tool.isort] @@ -67,7 +69,6 @@ profile = "black" [tool.black] string-normalization = false - [tool.pylint.'MESSAGES CONTROL'] disable=[ From 1468d146230b60d9c8e1630836422bd361915d60 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 12:15:14 -0700 Subject: [PATCH 07/36] Set up config initialization --- sweepai/cli.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/sweepai/cli.py b/sweepai/cli.py index eb57aaba91..e1cb8efd89 100644 --- a/sweepai/cli.py +++ b/sweepai/cli.py @@ -1,4 +1,5 @@ import datetime +import json import os import pickle import threading @@ -12,6 +13,7 @@ from github.Repository import Repository from loguru import logger from rich.console import Console +from rich.prompt import Prompt from sweepai.api import handle_request from sweepai.handlers.on_ticket import on_ticket @@ -20,10 +22,21 @@ from sweepai.web.events import Account, Installation, IssueRequest app = typer.Typer() +app_dir = typer.get_app_dir("sweepai") +config_path = os.path.join(app_dir, "config.json") console = Console() cprint = console.print +if os.path.exists(config_path): + cprint(f"\nLoading configuration from {config_path}", style="yellow") + with open(config_path, "r") as f: + config = json.load(f) + GITHUB_PAT = config.get("GITHUB_PAT", "") + os.environ["GITHUB_PAT"] = config.get("GITHUB_PAT", "") + OPENAI_API_KEY = config.get("OPENAI_API_KEY", "") + os.environ["OPENAI_API_KEY"] = config.get("OPENAI_API_KEY", "") + def fetch_issue_request(issue_url: str, __version__: str = "0"): ( @@ -101,6 +114,14 @@ def watch( record_events: bool = False, max_events: int = 30, ): + if not os.path.exists(config_path): + cprint( + f"\nConfiguration not found at {config_path}. Please run [green]'sweep init'[/green] to initialize the CLI.\n", + style="yellow", + ) + raise ValueError( + "Configuration not found, please run 'sweep init' to initialize the CLI." + ) GITHUB_PAT = os.environ.get("GITHUB_PAT", None) if GITHUB_PAT is None: raise ValueError("GITHUB_PAT environment variable must be set") @@ -188,8 +209,59 @@ def main(): main() +@app.command() +def init(override: bool = False): + if os.path.exists(config_path) and not override: + override = typer.confirm( + f"\nConfiguration already exists at {config_path}. Override?", + default=False, + abort=True, + ) + cprint( + f"\n[bold black on white] Initializing Sweep CLI... [/bold black on white]\n", + ) + cprint( + f"Firstly, we'll need your OpenAI API Key. You can get it here: https://platform.openai.com/api-keys\n", + style="yellow", + ) + openai_api_key = Prompt.ask("OpenAI API Key", password=True) + assert len(openai_api_key) > 30, "OpenAI API Key must be of length at least 30." + assert openai_api_key.startswith("sk-"), "OpenAI API Key must start with 'sk-'." + cprint( + f"\nGreat! Next, we'll need your GitHub PAT. Here's a link with all the permissions pre-filled:\nhttps://github.com/settings/tokens/new?description=Sweep%20Self-hosted&scopes=repo,workflow\n", + style="yellow", + ) + github_pat = Prompt.ask("GitHub PAT", password=True) + assert len(github_pat) > 30, "GitHub PAT must be of length at least 30." + assert github_pat.startswith("ghp_"), "GitHub PAT must start with 'ghp_'." + + config = { + "GITHUB_PAT": github_pat, + "OPENAI_API_KEY": openai_api_key, + } + os.makedirs(app_dir, exist_ok=True) + with open(config_path, "w") as f: + json.dump(config, f) + + cprint(f"\nConfiguration saved to {config_path}\n", style="yellow") + + cprint( + f"Installation complete! You can now run [green]'sweep run '[/green][yellow] to run Sweep on an issue. or [/yellow][green]'sweep watch /'[/green] to have Sweep listen for and fix newly created GitHub issues.", + style="yellow", + ) + + @app.command() def run(issue_url: str): + if not os.path.exists(config_path): + cprint( + f"\nConfiguration not found at {config_path}. Please run [green]'sweep init'[/green] to initialize the CLI.\n", + style="yellow", + ) + raise ValueError( + "Configuration not found, please run 'sweep init' to initialize the CLI." + ) + cprint(f"\n Running Sweep on issue: {issue_url} \n", style="bold black on white") request = fetch_issue_request(issue_url) From a58ec7c92e86b70c6be8891799d598e9ee5c52e9 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 12:20:56 -0700 Subject: [PATCH 08/36] Updated CLI page --- docs/pages/cli.mdx | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/docs/pages/cli.mdx b/docs/pages/cli.mdx index e87e4a00fd..16b438022b 100644 --- a/docs/pages/cli.mdx +++ b/docs/pages/cli.mdx @@ -7,33 +7,21 @@ Sweep CLI is a way to try out Sweep without the data entering our servers. It's This is a guide for running the Sweep CLI. To use our hosted version please visit https://github.com/apps/sweep-ai, and to self-host the GitHub App, visit [here](/deployment). -Prerequisites: you need Python 3.10 and pip installed. +Prerequisites: you need Python 3.10 and pip installed, an OpenAI account and a GitHub account. -### GitHub Personal Access Token - -To allow Sweep to access your repo(s), create a new [GitHub Personal Access Token (PAT) here](https://github.com/settings/tokens/new?description=Sweep%20Self-hosted&scopes=repo,workflow). Sweep will run entirely locally, and no code will be shared outside of OpenAI's API and GitHub. - -Add this to your `.env` which should now look like this: +### Install the Sweep CLI -```sh filename=".env" -REPO=your-username/your-repo -GITHUB_PAT=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +```sh filename="terminal" +pip install sweepai ``` -### OpenAI API Key +### Initialize the Sweep CLI -Create an OpenAI API token at https://platform.openai.com/account/api-keys and add it to your `.env` file which should now look like this: -```sh filename=".env" -REPO=your-username/your-repo -GITHUB_PAT=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -``` - -### Install the Sweep CLI +Initialize the CLI with your GitHub and OpenAI API keys by running the following command and following the prompts: ```sh filename="terminal" -pip install sweepai +sweep init ``` ### Run the Sweep CLI From 26e02bf681940c395c97b6151f51657d7eeadfd2 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 12:27:10 -0700 Subject: [PATCH 09/36] Minor update --- docs/pages/cli.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/cli.mdx b/docs/pages/cli.mdx index 541dd1b2fe..b4f8a40675 100644 --- a/docs/pages/cli.mdx +++ b/docs/pages/cli.mdx @@ -2,7 +2,7 @@ import { Callout, Tabs, Steps } from 'nextra/components' import { FaInfoCircle, FaExclamationCircle } from 'react-icons/fa' # Sweep CLI Installation -Prerequisites: **python 3.10, pip, OpenAI account and GitHub account** +Prerequisites: **python 3.10, pip, an OpenAI account and a GitHub account** Sweep CLI is a locally running version of Sweep (no data will enter our servers).
From 5560183bd9da1b9aed7271a1d005b7c554fcc5a8 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 12:28:51 -0700 Subject: [PATCH 10/36] Ruff --- sweepai/cli.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sweepai/cli.py b/sweepai/cli.py index e1cb8efd89..f40d62091a 100644 --- a/sweepai/cli.py +++ b/sweepai/cli.py @@ -218,17 +218,17 @@ def init(override: bool = False): abort=True, ) cprint( - f"\n[bold black on white] Initializing Sweep CLI... [/bold black on white]\n", + "\n[bold black on white] Initializing Sweep CLI... [/bold black on white]\n", ) cprint( - f"Firstly, we'll need your OpenAI API Key. You can get it here: https://platform.openai.com/api-keys\n", + "Firstly, we'll need your OpenAI API Key. You can get it here: https://platform.openai.com/api-keys\n", style="yellow", ) openai_api_key = Prompt.ask("OpenAI API Key", password=True) assert len(openai_api_key) > 30, "OpenAI API Key must be of length at least 30." assert openai_api_key.startswith("sk-"), "OpenAI API Key must start with 'sk-'." cprint( - f"\nGreat! Next, we'll need your GitHub PAT. Here's a link with all the permissions pre-filled:\nhttps://github.com/settings/tokens/new?description=Sweep%20Self-hosted&scopes=repo,workflow\n", + "\nGreat! Next, we'll need your GitHub PAT. Here's a link with all the permissions pre-filled:\nhttps://github.com/settings/tokens/new?description=Sweep%20Self-hosted&scopes=repo,workflow\n", style="yellow", ) github_pat = Prompt.ask("GitHub PAT", password=True) @@ -246,7 +246,7 @@ def init(override: bool = False): cprint(f"\nConfiguration saved to {config_path}\n", style="yellow") cprint( - f"Installation complete! You can now run [green]'sweep run '[/green][yellow] to run Sweep on an issue. or [/yellow][green]'sweep watch /'[/green] to have Sweep listen for and fix newly created GitHub issues.", + "Installation complete! You can now run [green]'sweep run '[/green][yellow] to run Sweep on an issue. or [/yellow][green]'sweep watch /'[/green] to have Sweep listen for and fix newly created GitHub issues.", style="yellow", ) From 35a14da8d457570d35145e04111aba50a817af19 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 15:34:30 -0700 Subject: [PATCH 11/36] Versioning fix --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 259b7ab8d9..55c1ef83c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ Homepage = "https://sweep.dev" [project] name = "sweepai" -version = "1.0.12" +version = "1.0.13" description = "Sweep fixes GitHub issues" authors = [ {name = "Kevin Lu", email = "kevin@sweep.dev"}, From 085504dd9d2329b2cce8885b299abd056bed092f Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 15:40:44 -0700 Subject: [PATCH 12/36] Combined the CI/CD --- .github/workflows/python.yml | 79 ++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .github/workflows/python.yml diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 0000000000..3fd8dd1d57 --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,79 @@ +name: Full CI Pipeline + +on: + pull_request: + branches: + - main + - dev + paths: + - 'sweepai/**' + - 'tests/**' + push: + branches: + - main + - dev + paths: + - 'sweepai/**' + - 'tests/**' + +jobs: + build-and-test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11"] + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Cache Python dependencies + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt', '**/pyproject.toml') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + pip install -r requirements.txt + pip install black ruff pylint uvicorn pytest + + - name: Format code with Black + run: black --check . + + - name: Lint with Ruff + run: ruff check sweepai + + - name: Lint with Pylint + run: pylint sweepai --errors-only + + - name: Run Unit Tests + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + run: python -m unittest sweepai/**/*_test.py + + - name: Set up Redis (for e2e tests) + run: | + sudo apt-get update + sudo apt-get install redis-server + sudo lsof -i :6379 || true + + - name: Run e2e Tests + env: + GITHUB_PAT: ${{ secrets.GH_PAT }} + GITHUB_APP_ID: ${{ secrets.GH_APP_ID }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + GITHUB_APP_PEM: ${{ secrets.GH_APP_PEM }} + OPENAI_API_TYPE: azure + OPENAI_API_BASE: ${{ secrets.GH_OPENAI_API_BASE }} + OPENAI_API_VERSION: 2024-02-15-preview + AZURE_API_KEY: ${{ secrets.GH_AZURE_API_KEY }} + AZURE_OPENAI_DEPLOYMENT: ${{ secrets.GH_AZURE_OPENAI_DEPLOYMENT }} + run: PYTHONPATH=. pytest -n 4 tests/e2e -s + timeout-minutes: 30 From f7658764543680883aeeda0f71f22c5ddeab3aa9 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 15:45:01 -0700 Subject: [PATCH 13/36] Improved Ci/Cd --- .github/workflows/python.yml | 41 +++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 3fd8dd1d57..60fc44e45c 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -17,11 +17,13 @@ on: - 'tests/**' jobs: - build-and-test: + setup-and-dependencies: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.10", "3.11"] + outputs: + cache-key: ${{ steps.cache-dependencies.outputs.cache-key }} steps: - name: Checkout code uses: actions/checkout@v3 @@ -32,6 +34,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache Python dependencies + id: cache-dependencies uses: actions/cache@v3 with: path: ~/.cache/pip @@ -44,6 +47,18 @@ jobs: pip install -r requirements.txt pip install black ruff pylint uvicorn pytest + code-quality: + needs: setup-and-dependencies + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Use Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 # Choose based on your project's needs + - name: Format code with Black run: black --check . @@ -53,11 +68,35 @@ jobs: - name: Lint with Pylint run: pylint sweepai --errors-only + unit-tests: + needs: setup-and-dependencies + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Use Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 # Choose based on your project's needs + - name: Run Unit Tests env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: python -m unittest sweepai/**/*_test.py + e2e-tests: + needs: unit-tests + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 # Choose based on your project's needs + - name: Set up Redis (for e2e tests) run: | sudo apt-get update From 4ef68a2f4d595260c9baa751453545b54e17e663 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 15:47:24 -0700 Subject: [PATCH 14/36] Docs fix --- docs/pages/cli.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/cli.mdx b/docs/pages/cli.mdx index 68b4c387e0..7f8f7e6221 100644 --- a/docs/pages/cli.mdx +++ b/docs/pages/cli.mdx @@ -2,7 +2,7 @@ import { Callout, Tabs, Steps } from 'nextra/components' import { FaInfoCircle, FaExclamationCircle } from 'react-icons/fa' # Sweep CLI Installation -Prerequisites: **python 3.10, pip, an OpenAI account and a GitHub account** +Prerequisites: **python 3.10 and pip** Sweep CLI is a locally running version of Sweep (no data will enter our servers).
From e225c18942c3f09129ccb5b45accac386ebfafb9 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 15:47:51 -0700 Subject: [PATCH 15/36] Change in python code to test CI --- sweepai/cli_test.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 sweepai/cli_test.py diff --git a/sweepai/cli_test.py b/sweepai/cli_test.py new file mode 100644 index 0000000000..3f1d3eb1c2 --- /dev/null +++ b/sweepai/cli_test.py @@ -0,0 +1,15 @@ +# import unittest +# from unittest.mock import patch, mock_open + +# class TestConfigLoading(unittest.TestCase): +# @patch('os.path.exists') +# @patch('builtins.open', new_callable=mock_open, read_data='{"GITHUB_PAT": "test", "OPENAI_API_KEY": "test"}') +# def test_load_config(self, mock_file, mock_exists): +# mock_exists.return_value = True +# # Your function to load config here, e.g., load_config() +# # Assert the configuration has been loaded correctly +# self.assertEqual(config['GITHUB_PAT'], 'test') +# self.assertEqual(config['OPENAI_API_KEY'], 'test') + +# if __name__ == '__main__': +# unittest.main() From e0fe1903710b86e0e33d2256c84dffdc40fdbc45 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 15:51:32 -0700 Subject: [PATCH 16/36] Python E2E Fix --- .github/workflows/python.yml | 62 ++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 60fc44e45c..75793b757e 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -5,9 +5,9 @@ on: branches: - main - dev - paths: - - 'sweepai/**' - - 'tests/**' + # paths: + # - 'sweepai/**' + # - 'tests/**' push: branches: - main @@ -25,27 +25,41 @@ jobs: outputs: cache-key: ${{ steps.cache-dependencies.outputs.cache-key }} steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - - name: Cache Python dependencies - id: cache-dependencies - uses: actions/cache@v3 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt', '**/pyproject.toml') }} - restore-keys: | - ${{ runner.os }}-pip- - - - name: Install dependencies - run: | - pip install -r requirements.txt - pip install black ruff pylint uvicorn pytest + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: 1.67.0 + override: true + - uses: Swatinem/rust-cache@v1 + - uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV + - run: pip install uv + - run: uv pip install -r requirements.txt + - run: uv pip install black ruff pylint uvicorn pytest + # - name: Checkout code + # uses: actions/checkout@v3 + + # - name: Set up Python + # uses: actions/setup-python@v4 + # with: + # python-version: ${{ matrix.python-version }} + + # - name: Cache Python dependencies + # id: cache-dependencies + # uses: actions/cache@v3 + # with: + # path: ~/.cache/pip + # key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt', '**/pyproject.toml') }} + # restore-keys: | + # ${{ runner.os }}-pip- + + # - name: Install dependencies + # run: | + # pip install -r requirements.txt + # pip install black ruff pylint uvicorn pytest code-quality: needs: setup-and-dependencies From d26fdee5a7410ba6aff99324d5c7374dc6336c77 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 16:43:09 -0700 Subject: [PATCH 17/36] Initial tests --- .github/workflows/python.yml | 2 +- sweepai/cli.py | 20 +++++---- sweepai/cli_test.py | 52 +++++++++++++++++------- tests/e2e/test_cli_run.py | 78 ++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 24 deletions(-) create mode 100644 tests/e2e/test_cli_run.py diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 75793b757e..efc3193c05 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -1,4 +1,4 @@ -name: Full CI Pipeline +name: Python CI All on: pull_request: diff --git a/sweepai/cli.py b/sweepai/cli.py index f40d62091a..e73dc9d791 100644 --- a/sweepai/cli.py +++ b/sweepai/cli.py @@ -28,14 +28,17 @@ console = Console() cprint = console.print -if os.path.exists(config_path): - cprint(f"\nLoading configuration from {config_path}", style="yellow") - with open(config_path, "r") as f: - config = json.load(f) - GITHUB_PAT = config.get("GITHUB_PAT", "") - os.environ["GITHUB_PAT"] = config.get("GITHUB_PAT", "") - OPENAI_API_KEY = config.get("OPENAI_API_KEY", "") - os.environ["OPENAI_API_KEY"] = config.get("OPENAI_API_KEY", "") + +def load_config(): + if os.path.exists(config_path): + cprint(f"\nLoading configuration from {config_path}", style="yellow") + with open(config_path, "r") as f: + config = json.load(f) + print(config) + config.get("GITHUB_PAT", "") + os.environ["GITHUB_PAT"] = config.get("GITHUB_PAT", "") + config.get("OPENAI_API_KEY", "") + os.environ["OPENAI_API_KEY"] = config.get("OPENAI_API_KEY", "") def fetch_issue_request(issue_url: str, __version__: str = "0"): @@ -283,4 +286,5 @@ def run(issue_url: str): if __name__ == "__main__": + load_config() app() diff --git a/sweepai/cli_test.py b/sweepai/cli_test.py index 3f1d3eb1c2..031927063e 100644 --- a/sweepai/cli_test.py +++ b/sweepai/cli_test.py @@ -1,15 +1,37 @@ -# import unittest -# from unittest.mock import patch, mock_open - -# class TestConfigLoading(unittest.TestCase): -# @patch('os.path.exists') -# @patch('builtins.open', new_callable=mock_open, read_data='{"GITHUB_PAT": "test", "OPENAI_API_KEY": "test"}') -# def test_load_config(self, mock_file, mock_exists): -# mock_exists.return_value = True -# # Your function to load config here, e.g., load_config() -# # Assert the configuration has been loaded correctly -# self.assertEqual(config['GITHUB_PAT'], 'test') -# self.assertEqual(config['OPENAI_API_KEY'], 'test') - -# if __name__ == '__main__': -# unittest.main() +import json +import os +import unittest +from unittest.mock import mock_open, patch + +from sweepai.cli import load_config, run + + +class TestConfigLoading(unittest.TestCase): + @patch.dict(os.environ, {}, clear=True) + @patch("os.path.exists", return_value=True) + @patch( + "builtins.open", + new_callable=mock_open, + read_data=json.dumps( + {"GITHUB_PAT": "test_github_pat", "OPENAI_API_KEY": "test_openai_key"} + ), + ) + def test_load_config(self, mock_file, mock_exists): + with self.assertRaises(KeyError): + os.environ["GITHUB_PAT"] + with self.assertRaises(KeyError): + os.environ["OPENAI_API_KEY"] + load_config() + self.assertEqual(os.environ["GITHUB_PAT"], "test_github_pat") + self.assertEqual(os.environ["OPENAI_API_KEY"], "test_openai_key") + + +class TestCLIRunIsssue(unittest.TestCase): + @patch("os.path.exists", return_value=False) + def test_run_issue_no_config(self, mock_exists): + with self.assertRaises(ValueError): + run("https://github.com/sweepai/e2e/issues/1") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/e2e/test_cli_run.py b/tests/e2e/test_cli_run.py new file mode 100644 index 0000000000..e383659feb --- /dev/null +++ b/tests/e2e/test_cli_run.py @@ -0,0 +1,78 @@ +import datetime +import json +import os +import tempfile +import time + +import pytest +from github import Github +from github.PaginatedList import PaginatedList +from github.PullRequest import PullRequest +from typer.testing import CliRunner + +from sweepai.cli import app, load_config + +issue_json = json.load(open("tests/jsons/e2e_button_to_green.json", "r")) +local_tz = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo + +runner = CliRunner() + + +@pytest.fixture(autouse=True) +def setup_config(): + with tempfile.TemporaryDirectory() as tmp_dir: + import sweepai.cli + + original_app_dir = sweepai.cli.app_dir + original_config_path = sweepai.cli.config_path + + app_dir = tmp_dir + os.path.join(app_dir, "config.json") + + yield + + sweepai.cli.app_dir = original_app_dir + sweepai.cli.config_path = original_config_path + + +@pytest.fixture(autouse=True) +def clean_env(): + original_env = os.environ.copy() + os.environ.clear() + yield + os.environ.clear() + os.environ.update(original_env) + + +def test_cli(): + assert os.environ.get("OPENAI_API_KEY") is None + assert os.environ.get("GITHUB_PAT") is None + load_config() + assert os.environ.get("OPENAI_API_KEY") is not None + assert os.environ.get("GITHUB_PAT") is not None + + +def test_run(): + issue_title = issue_json["issue"]["title"] + load_config() + result = runner.invoke(app, ["run", "https://github.com/sweepai/e2e/issues/1"]) + + repo = Github(os.environ["GITHUB_PAT"]).get_repo("sweepai/e2e") + pulls: PaginatedList[PullRequest] = repo.get_pulls( + state="open", sort="created", direction="desc" + ) + for pr in pulls[: pulls.totalCount]: + current_date = time.time() - 60 * 2 + current_date = datetime.datetime.fromtimestamp(current_date) + creation_date: datetime.datetime = pr.created_at.replace( + tzinfo=datetime.timezone.utc + ).astimezone(local_tz) + # success if a new pr was made within i+1 minutes ago + if ( + issue_title in pr.title + and creation_date.timestamp() > current_date.timestamp() + ): + print(f"PR created successfully: {pr.title}") + print(f"PR object is: {pr}") + return pr + raise AssertionError("PR not created") From c0accee65ba9fab7113bb3c5a402eadfc896f463 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 16:44:46 -0700 Subject: [PATCH 18/36] Cleanup --- .github/workflows/black.yml | 27 --------------- .github/workflows/e2e.yml | 62 ---------------------------------- .github/workflows/pylint.yml | 41 ---------------------- .github/workflows/python.yml | 21 ------------ .github/workflows/unittest.yml | 46 ------------------------- 5 files changed, 197 deletions(-) delete mode 100644 .github/workflows/black.yml delete mode 100644 .github/workflows/e2e.yml delete mode 100644 .github/workflows/pylint.yml delete mode 100644 .github/workflows/unittest.yml diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml deleted file mode 100644 index dda4c468ac..0000000000 --- a/.github/workflows/black.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Black Formatter - -on: - pull_request: - branches: - - main - - dev - paths: - - 'sweepai/**' - - 'tests/**' - push: - branches: - - main - paths: - - 'sweepai/**' - - 'tests/**' - -jobs: - black: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - name: Run Black - run: | - pip install black - black . diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml deleted file mode 100644 index a85b6ee209..0000000000 --- a/.github/workflows/e2e.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: e2e Tests - -on: - pull_request: - branches: - - main - - dev - paths: - - 'sweepai/**' - - 'tests/**' - push: - branches: - - main - paths: - - 'sweepai/**' - - 'tests/**' - - -jobs: - unittest: - runs-on: ${{ matrix.os }} - strategy: - matrix: - python-version: ["3.10"] - # os: [ubuntu-latest, macos-latest] - os: [ubuntu-latest] - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: 1.67.0 - override: true - - uses: Swatinem/rust-cache@v1 - - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - - run: pip install uv - - run: uv pip install -r requirements.txt - - run: pylint sweepai --errors-only - - run: ruff check sweepai - - # apparently installing redis-server runs it automatically - - name: Set up Redis - run: | - sudo apt-get update; sudo apt-get install redis-server; - sudo lsof -i :6379 || true - - - name: Run e2e test - env: - GITHUB_PAT: ${{ secrets.GH_PAT }} - GITHUB_APP_ID: ${{ secrets.GH_APP_ID }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - GITHUB_APP_PEM: ${{ secrets.GH_APP_PEM }} - OPENAI_API_TYPE: azure - OPENAI_API_BASE: ${{ secrets.GH_OPENAI_API_BASE }} - OPENAI_API_VERSION: 2024-02-15-preview - AZURE_API_KEY: ${{ secrets.GH_AZURE_API_KEY }} - AZURE_OPENAI_DEPLOYMENT: ${{ secrets.GH_AZURE_OPENAI_DEPLOYMENT }} - run: PYTHONPATH=. pytest -n 4 tests/e2e -s - timeout-minutes: 30 diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml deleted file mode 100644 index d63ccc5c75..0000000000 --- a/.github/workflows/pylint.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Pylint - -on: - pull_request: - branches: - - main - - dev - paths: - - 'sweepai/**' - - 'tests/**' - push: - branches: - - main - paths: - - 'sweepai/**' - - 'tests/**' - -jobs: - pylint: - runs-on: ${{ matrix.os }} - strategy: - matrix: - python-version: ["3.10", "3.11"] - # os: [ubuntu-latest, macos-latest] - os: [ubuntu-latest] - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: 1.67.0 - override: true - - uses: Swatinem/rust-cache@v1 - - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - - run: pip install uv - - run: uv pip install -r requirements.txt - - run: pylint sweepai --errors-only - - run: ruff check sweepai diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index efc3193c05..8f36097658 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -39,27 +39,6 @@ jobs: - run: pip install uv - run: uv pip install -r requirements.txt - run: uv pip install black ruff pylint uvicorn pytest - # - name: Checkout code - # uses: actions/checkout@v3 - - # - name: Set up Python - # uses: actions/setup-python@v4 - # with: - # python-version: ${{ matrix.python-version }} - - # - name: Cache Python dependencies - # id: cache-dependencies - # uses: actions/cache@v3 - # with: - # path: ~/.cache/pip - # key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt', '**/pyproject.toml') }} - # restore-keys: | - # ${{ runner.os }}-pip- - - # - name: Install dependencies - # run: | - # pip install -r requirements.txt - # pip install black ruff pylint uvicorn pytest code-quality: needs: setup-and-dependencies diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml deleted file mode 100644 index 86b84e457f..0000000000 --- a/.github/workflows/unittest.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Python Unit Tests - -on: - pull_request: - branches: - - main - - dev - paths: - - 'sweepai/**' - - 'tests/**' - push: - branches: - - main - paths: - - 'sweepai/**' - - 'tests/**' - -jobs: - unittest: - runs-on: ${{ matrix.os }} - strategy: - matrix: - python-version: ["3.10", "3.11"] - # os: [ubuntu-latest, macos-latest] - os: [ubuntu-latest] - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: 1.67.0 - override: true - - uses: Swatinem/rust-cache@v1 - - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - - run: pip install uv - - run: uv pip install -r requirements.txt - - run: pylint sweepai --errors-only - - run: ruff check sweepai - - - name: Run unittest - env: - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - run: python -m unittest sweepai/**/*_test.py From 4c6ce5977f388172daebabc7911889a5ab782b3d Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 16:53:40 -0700 Subject: [PATCH 19/36] Increase rate of function calls --- sweepai/agents/assistant_function_modify.py | 93 ++++++++++++++------- 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/sweepai/agents/assistant_function_modify.py b/sweepai/agents/assistant_function_modify.py index 5b44b3e831..d48f2ce77b 100644 --- a/sweepai/agents/assistant_function_modify.py +++ b/sweepai/agents/assistant_function_modify.py @@ -1,7 +1,7 @@ -from collections import defaultdict import json import textwrap import traceback +from collections import defaultdict from loguru import logger @@ -24,7 +24,7 @@ You NEVER leave comments describing code without implementing it! Always use best practices when coding. Respect and use existing conventions, libraries, etc that are already present in the code base. -Your job is to make edits to the file to complete the user "# Request". +Your job is to make edits to the file to complete the user "# Request" by making function calls. # Instructions 1. Use the propose_problem_analysis_and_plan function to analyze the user's request and construct a plan of keywords to search for and the changes to make. @@ -84,24 +84,30 @@ def ensure_additional_messages_length(additional_messages: list[Message]): ) return additional_messages -def read_file_with_fallback_encodings(file_path, encodings=['utf-8', 'windows-1252', 'iso-8859-1']): + +def read_file_with_fallback_encodings( + file_path, encodings=["utf-8", "windows-1252", "iso-8859-1"] +): for encoding in encodings: try: - with open(file_path, 'r', encoding=encoding) as file: + with open(file_path, "r", encoding=encoding) as file: return file.read() except UnicodeDecodeError: continue - raise UnicodeDecodeError(f"Could not decode {file_path} with any of the specified encodings: {encodings}") + raise UnicodeDecodeError( + f"Could not decode {file_path} with any of the specified encodings: {encodings}" + ) + -def build_keyword_search_match_results(match_indices: list[int], chunks: list[str], keyword: str, success_message) -> str: +def build_keyword_search_match_results( + match_indices: list[int], chunks: list[str], keyword: str, success_message +) -> str: for match_index in match_indices: # TODO: handle multiple matches in one line match = chunks[match_index] match_lines = match.split("\n") lines_containing_keyword = [ - i - for i, line in enumerate(match_lines) - if keyword in line + i for i, line in enumerate(match_lines) if keyword in line ] cols_of_keyword = [ match_lines[line_containing_keyword].index(keyword) @@ -112,12 +118,7 @@ def build_keyword_search_match_results(match_indices: list[int], chunks: list[st if i in lines_containing_keyword: match_display += ( f"{line}\n" - + " " - * ( - cols_of_keyword[ - lines_containing_keyword.index(i) - ] - ) + + " " * (cols_of_keyword[lines_containing_keyword.index(i)]) + "^\n" ) else: @@ -156,10 +157,14 @@ def save_ticket_progress(assistant_id: str, thread_id: str, run_id: str): # get code for relevant filepaths try: for relevant_file_path in relevant_filepaths: - relevant_file_content = read_file_with_fallback_encodings(relevant_file_path) + relevant_file_content = read_file_with_fallback_encodings( + relevant_file_path + ) relevant_file_contents[relevant_file_path] = relevant_file_content except Exception as e: - logger.error(f"Error occured while attempting to fetch contents for relevant file: {e}") + logger.error( + f"Error occured while attempting to fetch contents for relevant file: {e}" + ) initial_code_valid, _ = check_code(file_path, current_contents) initial_code_valid = initial_code_valid or ( "<<<<<<<" in current_contents and ">>>>>>>" in current_contents @@ -171,7 +176,9 @@ def save_ticket_progress(assistant_id: str, thread_id: str, run_id: str): relevant_file_snippets: dict[str, list[Snippet]] = defaultdict(list) # now we chunk relevant file contents for relevant_file_path, relevant_file_content in relevant_file_contents.items(): - relevant_file_snippet = chunk_code(relevant_file_content, relevant_file_path, 700, 200) + relevant_file_snippet = chunk_code( + relevant_file_content, relevant_file_path, 700, 200 + ) relevant_file_snippets[relevant_file_path] = relevant_file_snippet file_contents_lines = current_contents.split("\n") @@ -396,7 +403,9 @@ def save_ticket_progress(assistant_id: str, thread_id: str, run_id: str): if not error_message: keyword = tool_call["keyword"] match_indices = [] - relevant_file_match_indices: dict[str, list[int]] = defaultdict(list) + relevant_file_match_indices: dict[str, list[int]] = defaultdict( + list + ) # search current code file for i, chunk in enumerate(chunks): if keyword in chunk: @@ -404,28 +413,54 @@ def save_ticket_progress(assistant_id: str, thread_id: str, run_id: str): match_indices.append(i) match_indices.append(min(len(chunks) - 1, i + 1)) # search all relevant code files - for relevant_file_path, relevant_file_chunk_group in relevant_file_chunks.items(): + for ( + relevant_file_path, + relevant_file_chunk_group, + ) in relevant_file_chunks.items(): for i, chunk in enumerate(relevant_file_chunk_group): if keyword in chunk: - relevant_file_match_indices[relevant_file_path].append(max(0, i - 1)) - relevant_file_match_indices[relevant_file_path].append(i) - relevant_file_match_indices[relevant_file_path].append(min(len(relevant_file_chunk_group) - 1, i + 1)) - + relevant_file_match_indices[ + relevant_file_path + ].append(max(0, i - 1)) + relevant_file_match_indices[ + relevant_file_path + ].append(i) + relevant_file_match_indices[ + relevant_file_path + ].append( + min(len(relevant_file_chunk_group) - 1, i + 1) + ) + match_indices = sorted(list(set(match_indices))) - relevant_file_match_indices = {k: sorted(list(set(v))) for k, v in relevant_file_match_indices.items()} + relevant_file_match_indices = { + k: sorted(list(set(v))) + for k, v in relevant_file_match_indices.items() + } if not match_indices and not relevant_file_match_indices: error_message = f"The keyword {keyword} does not appear to be present in the code. Consider missing or misplaced whitespace, comments or delimiters." else: # for matches inside current code file if match_indices: starter_message = f"The keyword {keyword} was found in the following sections:\n\n" - success_message += build_keyword_search_match_results(match_indices, chunks, keyword, starter_message) + success_message += build_keyword_search_match_results( + match_indices, chunks, keyword, starter_message + ) # for matches inside relevant code files if relevant_file_match_indices: - for relevant_file_path, relevant_file_match_indices in relevant_file_match_indices.items(): + for ( + relevant_file_path, + relevant_file_match_indices, + ) in relevant_file_match_indices.items(): starter_message = f"The keyword {keyword} was found in the following sections of the relevant file {relevant_file_path}:\n\n" - success_message += build_keyword_search_match_results(relevant_file_match_indices, relevant_file_chunks[relevant_file_path], keyword, starter_message) - + success_message += ( + build_keyword_search_match_results( + relevant_file_match_indices, + relevant_file_chunks[relevant_file_path], + keyword, + starter_message, + ) + ) + if error_message: logger.debug(error_message) tool_name, tool_call = assistant_generator.send( From 517b07e829afe2847e2bb32cffe9723bacd1c520 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 16:54:13 -0700 Subject: [PATCH 20/36] Removed black --- .github/workflows/python.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 8f36097658..66e39fd312 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -52,9 +52,6 @@ jobs: with: python-version: 3.11 # Choose based on your project's needs - - name: Format code with Black - run: black --check . - - name: Lint with Ruff run: ruff check sweepai From 3a8a7efdce0514b1b907fe81f5b63e751c864353 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 17:07:35 -0700 Subject: [PATCH 21/36] Fix ruff --- .github/workflows/python.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 66e39fd312..bed36cc142 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -50,8 +50,9 @@ jobs: - name: Use Python uses: actions/setup-python@v4 with: - python-version: 3.11 # Choose based on your project's needs + python-version: 3.11 + - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - name: Lint with Ruff run: ruff check sweepai From d019cb4712ffdd5134d21a5c245e57b16acb3ad1 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 17:20:01 -0700 Subject: [PATCH 22/36] Function call fix --- sweepai/agents/assistant_function_modify.py | 2 +- sweepai/utils/openai_proxy.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sweepai/agents/assistant_function_modify.py b/sweepai/agents/assistant_function_modify.py index d48f2ce77b..a386a33976 100644 --- a/sweepai/agents/assistant_function_modify.py +++ b/sweepai/agents/assistant_function_modify.py @@ -24,7 +24,7 @@ You NEVER leave comments describing code without implementing it! Always use best practices when coding. Respect and use existing conventions, libraries, etc that are already present in the code base. -Your job is to make edits to the file to complete the user "# Request" by making function calls. +Your job is to make edits to the file to complete the user "# Request". # Instructions 1. Use the propose_problem_analysis_and_plan function to analyze the user's request and construct a plan of keywords to search for and the changes to make. diff --git a/sweepai/utils/openai_proxy.py b/sweepai/utils/openai_proxy.py index a5d21af2da..0cc10e53ca 100644 --- a/sweepai/utils/openai_proxy.py +++ b/sweepai/utils/openai_proxy.py @@ -99,7 +99,7 @@ def call_openai( engine = self.determine_openai_engine(model) if OPENAI_API_TYPE is None or engine is None: response = self.set_openai_default_api_parameters( - model, messages, max_tokens, temperature + model, messages, max_tokens, temperature, tools ) return response # validity checks for MULTI_REGION_CONFIG @@ -236,7 +236,7 @@ def call_azure_api(self, model, messages, tools, max_tokens, temperature): return response def set_openai_default_api_parameters( - self, model, messages, max_tokens, temperature, tools = [] + self, model, messages, max_tokens, temperature, tools=[] ): client = OpenAI(api_key=OPENAI_API_KEY) if len(tools) == 0: From 22616aaa66c08895e175c9f495858b2cf62254f0 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 17:49:39 -0700 Subject: [PATCH 23/36] Updated GHA --- .github/workflows/python.yml | 46 ++++++++++++++++++++++++++++++++---- pyproject.toml | 2 +- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index bed36cc142..220ca97269 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -35,10 +35,27 @@ jobs: - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - - run: pip install uv - - run: uv pip install -r requirements.txt - - run: uv pip install black ruff pylint uvicorn pytest + - name: Restore dependencies + id: restore-dependencies + uses: actions/cache/restore@v4 + with: + path: ~/.cache/uv + key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-python-${{ matrix.python-version }}- + ${{ runner.os }}-python- + - name: Install Python dependencies + if: steps.restore-dependencies.outputs.cache-hit != 'true' + run: | + pip install uv + uv pip install -r requirements.txt + uv pip install black ruff pylint uvicorn pytest + - name: Cache dependencies + id: cache-dependencies + uses: actions/cache/save@v4 + with: + path: ~/.cache/uv + key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} code-quality: needs: setup-and-dependencies @@ -52,6 +69,13 @@ jobs: with: python-version: 3.11 + - uses: actions/cache@v4 + name: Fetch dependencies + id: fetch-dependencies + with: + path: ~/.cache/uv + key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} + - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - name: Lint with Ruff run: ruff check sweepai @@ -71,6 +95,13 @@ jobs: with: python-version: 3.11 # Choose based on your project's needs + - uses: actions/cache@v4 + name: Fetch dependencies + id: fetch-dependencies + with: + path: ~/.cache/uv + key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} + - name: Run Unit Tests env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} @@ -88,6 +119,13 @@ jobs: with: python-version: 3.11 # Choose based on your project's needs + - uses: actions/cache@v4 + name: Fetch dependencies + id: fetch-dependencies + with: + path: ~/.cache/uv + key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} + - name: Set up Redis (for e2e tests) run: | sudo apt-get update diff --git a/pyproject.toml b/pyproject.toml index 55c1ef83c7..ae67b91212 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ Homepage = "https://sweep.dev" [project] name = "sweepai" -version = "1.0.13" +version = "1.1.0" description = "Sweep fixes GitHub issues" authors = [ {name = "Kevin Lu", email = "kevin@sweep.dev"}, From 1d80c07132ef0dd98b5d739e9890c35f900240c5 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 17:51:36 -0700 Subject: [PATCH 24/36] GHA Fixes --- .github/workflows/python.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 220ca97269..e642b3df49 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -48,6 +48,7 @@ jobs: if: steps.restore-dependencies.outputs.cache-hit != 'true' run: | pip install uv + echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV uv pip install -r requirements.txt uv pip install black ruff pylint uvicorn pytest - name: Cache dependencies @@ -95,6 +96,7 @@ jobs: with: python-version: 3.11 # Choose based on your project's needs + - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - uses: actions/cache@v4 name: Fetch dependencies id: fetch-dependencies @@ -126,6 +128,7 @@ jobs: path: ~/.cache/uv key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} + - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - name: Set up Redis (for e2e tests) run: | sudo apt-get update From 48f02e5fc996424411539aae3bec6c203e945612 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 17:54:32 -0700 Subject: [PATCH 25/36] GHA Fix --- .github/workflows/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index e642b3df49..37e6b8d2ef 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -47,8 +47,8 @@ jobs: - name: Install Python dependencies if: steps.restore-dependencies.outputs.cache-hit != 'true' run: | - pip install uv echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV + pip install uv uv pip install -r requirements.txt uv pip install black ruff pylint uvicorn pytest - name: Cache dependencies From 358de2cb94bcd03103925d4f7b5fa695055c7a91 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 17:57:02 -0700 Subject: [PATCH 26/36] GHA Fix --- .github/workflows/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 37e6b8d2ef..45b69a6669 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -50,7 +50,7 @@ jobs: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV pip install uv uv pip install -r requirements.txt - uv pip install black ruff pylint uvicorn pytest + # uv pip install black ruff pylint uvicorn pytest - name: Cache dependencies id: cache-dependencies uses: actions/cache/save@v4 From d8962c405af566a7ea3b0ba0f35e7f6c19c0d8eb Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:01:03 -0700 Subject: [PATCH 27/36] GHA Fix --- .github/workflows/python.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 45b69a6669..a839df464e 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -21,7 +21,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11"] + python-version: ["3.10"] + # python-version: ["3.10", "3.11"] outputs: cache-key: ${{ steps.cache-dependencies.outputs.cache-key }} steps: From 41940291729d4d990b2eb9a6d6b1b82a2edd132b Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:02:16 -0700 Subject: [PATCH 28/36] GHA Fix --- .github/workflows/python.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index a839df464e..96bef7718c 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -36,17 +36,17 @@ jobs: - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Restore dependencies - id: restore-dependencies - uses: actions/cache/restore@v4 - with: - path: ~/.cache/uv - key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-python-${{ matrix.python-version }}- - ${{ runner.os }}-python- + # - name: Restore dependencies + # id: restore-dependencies + # uses: actions/cache/restore@v4 + # with: + # path: ~/.cache/uv + # key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} + # restore-keys: | + # ${{ runner.os }}-python-${{ matrix.python-version }}- + # ${{ runner.os }}-python- - name: Install Python dependencies - if: steps.restore-dependencies.outputs.cache-hit != 'true' + # if: steps.restore-dependencies.outputs.cache-hit != 'true' run: | echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV pip install uv From 583a245920c85dc5cf985f62730522460dd2ffa3 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:05:33 -0700 Subject: [PATCH 29/36] README fix --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b48843f99..0b6e77f078 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ - - Better Stack Badge + + PyPI version Self Host Sweep Docker Image From 117f135449c407c487e2ef43854df66af8c240b6 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:06:42 -0700 Subject: [PATCH 30/36] GHA Fixes --- .github/workflows/python.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 96bef7718c..a4f4025a01 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -23,6 +23,7 @@ jobs: matrix: python-version: ["3.10"] # python-version: ["3.10", "3.11"] + os: [ubuntu-latest] outputs: cache-key: ${{ steps.cache-dependencies.outputs.cache-key }} steps: @@ -45,13 +46,16 @@ jobs: # restore-keys: | # ${{ runner.os }}-python-${{ matrix.python-version }}- # ${{ runner.os }}-python- - - name: Install Python dependencies - # if: steps.restore-dependencies.outputs.cache-hit != 'true' - run: | - echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - pip install uv - uv pip install -r requirements.txt - # uv pip install black ruff pylint uvicorn pytest + # - name: Install Python dependencies + # # if: steps.restore-dependencies.outputs.cache-hit != 'true' + # run: | + # echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV + # pip install uv + # uv pip install -r requirements.txt + # # uv pip install black ruff pylint uvicorn pytest + - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV + - run: pip install uv + - run: uv pip install -r requirements.txt - name: Cache dependencies id: cache-dependencies uses: actions/cache/save@v4 From e401a654ef62129352148587ecd9bbd2b5970ace Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:09:17 -0700 Subject: [PATCH 31/36] GHA Fixes --- .github/workflows/python.yml | 49 ++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index a4f4025a01..d1c72e024a 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -37,25 +37,21 @@ jobs: - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - # - name: Restore dependencies - # id: restore-dependencies - # uses: actions/cache/restore@v4 - # with: - # path: ~/.cache/uv - # key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} - # restore-keys: | - # ${{ runner.os }}-python-${{ matrix.python-version }}- - # ${{ runner.os }}-python- - # - name: Install Python dependencies - # # if: steps.restore-dependencies.outputs.cache-hit != 'true' - # run: | - # echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - # pip install uv - # uv pip install -r requirements.txt - # # uv pip install black ruff pylint uvicorn pytest + - name: Restore dependencies + id: restore-dependencies + uses: actions/cache/restore@v4 + with: + path: ~/.cache/uv + key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-python-${{ matrix.python-version }}- + ${{ runner.os }}-python- - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV + if: steps.restore-dependencies.outputs.cache-hit != 'true' - run: pip install uv + if: steps.restore-dependencies.outputs.cache-hit != 'true' - run: uv pip install -r requirements.txt + if: steps.restore-dependencies.outputs.cache-hit != 'true' - name: Cache dependencies id: cache-dependencies uses: actions/cache/save@v4 @@ -66,6 +62,11 @@ jobs: code-quality: needs: setup-and-dependencies runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10"] + # python-version: ["3.10", "3.11"] + os: [ubuntu-latest] steps: - name: Checkout code uses: actions/checkout@v3 @@ -73,7 +74,7 @@ jobs: - name: Use Python uses: actions/setup-python@v4 with: - python-version: 3.11 + python-version: 3.10 - uses: actions/cache@v4 name: Fetch dependencies @@ -92,6 +93,11 @@ jobs: unit-tests: needs: setup-and-dependencies runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10"] + # python-version: ["3.10", "3.11"] + os: [ubuntu-latest] steps: - name: Checkout code uses: actions/checkout@v3 @@ -99,7 +105,7 @@ jobs: - name: Use Python uses: actions/setup-python@v4 with: - python-version: 3.11 # Choose based on your project's needs + python-version: 3.10 # Choose based on your project's needs - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - uses: actions/cache@v4 @@ -117,6 +123,11 @@ jobs: e2e-tests: needs: unit-tests runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10"] + # python-version: ["3.10", "3.11"] + os: [ubuntu-latest] steps: - name: Checkout code uses: actions/checkout@v3 @@ -124,7 +135,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.11 # Choose based on your project's needs + python-version: 3.10 # Choose based on your project's needs - uses: actions/cache@v4 name: Fetch dependencies From 863694eef88e80887aee02026e354a63a4b1f635 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:11:14 -0700 Subject: [PATCH 32/36] --- .github/workflows/python.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index d1c72e024a..173f135080 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -74,7 +74,7 @@ jobs: - name: Use Python uses: actions/setup-python@v4 with: - python-version: 3.10 + python-version: ${{ matrix.python-version }} - uses: actions/cache@v4 name: Fetch dependencies @@ -105,7 +105,7 @@ jobs: - name: Use Python uses: actions/setup-python@v4 with: - python-version: 3.10 # Choose based on your project's needs + python-version: ${{ matrix.python-version }} - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - uses: actions/cache@v4 @@ -135,7 +135,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.10 # Choose based on your project's needs + python-version: ${{ matrix.python-version }} - uses: actions/cache@v4 name: Fetch dependencies From acc5c4f74953ca08f5a8998ec8f502e73fc0ae1d Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:13:52 -0700 Subject: [PATCH 33/36] --- .github/workflows/python.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 173f135080..d47db76672 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -52,6 +52,8 @@ jobs: if: steps.restore-dependencies.outputs.cache-hit != 'true' - run: uv pip install -r requirements.txt if: steps.restore-dependencies.outputs.cache-hit != 'true' + - run: uv pip install ruff pylint pytest pytest-xdist black + if: steps.restore-dependencies.outputs.cache-hit != 'true' - name: Cache dependencies id: cache-dependencies uses: actions/cache/save@v4 From c9663b20136a5056836980fa37095457238f4eb7 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:20:06 -0700 Subject: [PATCH 34/36] GHA Fixes --- .github/workflows/python.yml | 142 +++++++++-------------------------- 1 file changed, 35 insertions(+), 107 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index d47db76672..24c26101d4 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -41,7 +41,7 @@ jobs: id: restore-dependencies uses: actions/cache/restore@v4 with: - path: ~/.cache/uv + path: ~ key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-python-${{ matrix.python-version }}- @@ -58,111 +58,39 @@ jobs: id: cache-dependencies uses: actions/cache/save@v4 with: - path: ~/.cache/uv + path: ~ key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} - code-quality: - needs: setup-and-dependencies - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10"] - # python-version: ["3.10", "3.11"] - os: [ubuntu-latest] - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Use Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - - uses: actions/cache@v4 - name: Fetch dependencies - id: fetch-dependencies - with: - path: ~/.cache/uv - key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} - - - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - - name: Lint with Ruff - run: ruff check sweepai - - - name: Lint with Pylint - run: pylint sweepai --errors-only - - unit-tests: - needs: setup-and-dependencies - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10"] - # python-version: ["3.10", "3.11"] - os: [ubuntu-latest] - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Use Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - - uses: actions/cache@v4 - name: Fetch dependencies - id: fetch-dependencies - with: - path: ~/.cache/uv - key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} - - - name: Run Unit Tests - env: - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - run: python -m unittest sweepai/**/*_test.py - - e2e-tests: - needs: unit-tests - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10"] - # python-version: ["3.10", "3.11"] - os: [ubuntu-latest] - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - - uses: actions/cache@v4 - name: Fetch dependencies - id: fetch-dependencies - with: - path: ~/.cache/uv - key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} - - - run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV - - name: Set up Redis (for e2e tests) - run: | - sudo apt-get update - sudo apt-get install redis-server - sudo lsof -i :6379 || true - - - name: Run e2e Tests - env: - GITHUB_PAT: ${{ secrets.GH_PAT }} - GITHUB_APP_ID: ${{ secrets.GH_APP_ID }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - GITHUB_APP_PEM: ${{ secrets.GH_APP_PEM }} - OPENAI_API_TYPE: azure - OPENAI_API_BASE: ${{ secrets.GH_OPENAI_API_BASE }} - OPENAI_API_VERSION: 2024-02-15-preview - AZURE_API_KEY: ${{ secrets.GH_AZURE_API_KEY }} - AZURE_OPENAI_DEPLOYMENT: ${{ secrets.GH_AZURE_OPENAI_DEPLOYMENT }} - run: PYTHONPATH=. pytest -n 4 tests/e2e -s - timeout-minutes: 30 + - name: Format with Black + run: black sweepai + + - name: Lint with Ruff + run: ruff check sweepai + + - name: Lint with Pylint + run: pylint sweepai --errors-only + + - name: Run Unit Tests + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + run: python -m unittest sweepai/**/*_test.py + + - name: Set up Redis (for e2e tests) + run: | + sudo apt-get update + sudo apt-get install redis-server + sudo lsof -i :6379 || true + + - name: Run e2e Tests + env: + GITHUB_PAT: ${{ secrets.GH_PAT }} + GITHUB_APP_ID: ${{ secrets.GH_APP_ID }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + GITHUB_APP_PEM: ${{ secrets.GH_APP_PEM }} + OPENAI_API_TYPE: azure + OPENAI_API_BASE: ${{ secrets.GH_OPENAI_API_BASE }} + OPENAI_API_VERSION: 2024-02-15-preview + AZURE_API_KEY: ${{ secrets.GH_AZURE_API_KEY }} + AZURE_OPENAI_DEPLOYMENT: ${{ secrets.GH_AZURE_OPENAI_DEPLOYMENT }} + run: PYTHONPATH=. pytest -n 4 tests/e2e -s + timeout-minutes: 30 From 1cb043c5ef80471a3e53341ece67dd31f680d763 Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:21:08 -0700 Subject: [PATCH 35/36] GHA Fixes --- .github/workflows/python.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 24c26101d4..a4517f1f7b 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -41,7 +41,7 @@ jobs: id: restore-dependencies uses: actions/cache/restore@v4 with: - path: ~ + path: "~" key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-python-${{ matrix.python-version }}- @@ -58,7 +58,7 @@ jobs: id: cache-dependencies uses: actions/cache/save@v4 with: - path: ~ + path: "~" key: ${{ runner.os }}-python-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }} - name: Format with Black From 13726c8c0ca34a5c500db0a803dd0449b4d6a7ed Mon Sep 17 00:00:00 2001 From: Kevin Lu Date: Wed, 13 Mar 2024 18:37:10 -0700 Subject: [PATCH 36/36] Minor fix --- .github/workflows/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index a4517f1f7b..7441079404 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -17,7 +17,7 @@ on: - 'tests/**' jobs: - setup-and-dependencies: + python-ci: runs-on: ubuntu-latest strategy: matrix: