From 8f98a43bb6eea0e7925d5f013707ddc61ac7338a Mon Sep 17 00:00:00 2001 From: Hiroshi Nishio Date: Sun, 27 Oct 2024 15:52:03 -0700 Subject: [PATCH] Enable GitAuto to reply back when the ticket is not code-solvable to ask for more help, hints, and user actions --- services/check_run_handler.py | 8 +++++++ services/gitauto_handler.py | 7 ++++++ services/openai/commit_changes.py | 11 ++++++++-- services/openai/functions/update_comment.py | 22 +++++++++++++++++++ .../openai/instructions/update_comment.py | 14 ++++++++++++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 services/openai/functions/update_comment.py create mode 100644 services/openai/instructions/update_comment.py diff --git a/services/check_run_handler.py b/services/check_run_handler.py index 31f60323..2b910991 100644 --- a/services/check_run_handler.py +++ b/services/check_run_handler.py @@ -169,6 +169,14 @@ def handle_check_run(payload: CheckRunCompletedPayload) -> None: print(colorize(text="How to fix:", color="green")) print(how_to_fix) + # Update the comment if any obstacles are found + messages = [{"role": "user", "content": how_to_fix}] + _messages, _previous_calls, _token_input, _token_output, is_commented = ( + chat_with_agent(messages=messages, base_args=base_args, mode="comment") + ) + if is_commented: + return + content = { "pull_request_title": pull_title, "file_tree": file_tree, diff --git a/services/gitauto_handler.py b/services/gitauto_handler.py index f2c2cf89..aa13cf3e 100644 --- a/services/gitauto_handler.py +++ b/services/gitauto_handler.py @@ -171,7 +171,14 @@ async def handle_gitauto(payload: GitHubLabeledPayload, trigger_type: str) -> No ) base_args["pr_body"] = pr_body + # Update the comment if any obstacles are found messages = [{"role": "user", "content": pr_body}] + _messages, _previous_calls, token_input, token_output, is_solvable = ( + chat_with_agent(messages=messages, base_args=base_args, mode="comment") + ) + if not is_solvable: + return + # Create a remote branch comment_body = create_progress_bar(p=20, msg="Creating a remote branch...") update_comment(body=comment_body, base_args=base_args) diff --git a/services/openai/commit_changes.py b/services/openai/commit_changes.py index ac8c8e8e..f697d33b 100644 --- a/services/openai/commit_changes.py +++ b/services/openai/commit_changes.py @@ -19,6 +19,7 @@ TOOLS_TO_COMMIT_CHANGES, TOOLS_TO_EXPLORE_REPO, TOOLS_TO_GET_FILE, + TOOLS_TO_UPDATE_COMMENT, tools_to_call, ) from services.openai.init import create_openai_client @@ -26,6 +27,9 @@ SYSTEM_INSTRUCTION_TO_COMMIT_CHANGES, ) from services.openai.instructions.explore_repo import SYSTEM_INSTRUCTION_TO_EXPLORE_REPO +from services.openai.instructions.update_comment import ( + SYSTEM_INSTRUCTION_TO_UPDATE_COMMENT, +) from utils.colorize_log import colorize from utils.handle_exceptions import handle_exceptions @@ -34,7 +38,7 @@ def chat_with_agent( messages: Iterable[ChatCompletionMessageParam], base_args: BaseArgs, - mode: Literal["commit", "explore", "get"], + mode: Literal["comment", "commit", "explore", "get"], previous_calls: List[dict] | None = None, ): """https://platform.openai.com/docs/api-reference/chat/create""" @@ -42,7 +46,10 @@ def chat_with_agent( previous_calls = [] # Set the system message based on the mode - if mode == "commit": + if mode == "comment": + content = SYSTEM_INSTRUCTION_TO_UPDATE_COMMENT + tools = TOOLS_TO_UPDATE_COMMENT + elif mode == "commit": content = SYSTEM_INSTRUCTION_TO_COMMIT_CHANGES tools = TOOLS_TO_COMMIT_CHANGES elif mode == "explore": diff --git a/services/openai/functions/update_comment.py b/services/openai/functions/update_comment.py new file mode 100644 index 00000000..62298d05 --- /dev/null +++ b/services/openai/functions/update_comment.py @@ -0,0 +1,22 @@ +# Third-party imports +from openai.types import shared_params + +# OpenAI: We recommend including instructions regarding when to call a function in the system prompt, while using the function definition to provide instructions on how to call the function and how to generate the parameters. +# https://platform.openai.com/docs/guides/function-calling/should-i-include-function-call-instructions-in-the-tool-specification-or-in-the-system-prompt + +BODY: dict[str, str] = { + "type": "string", + "description": "The body of the comment.", +} + +UPDATE_GITHUB_COMMENT: shared_params.FunctionDefinition = { + "name": "update_github_comment", + "description": "Updates a comment in GitHub issue or GitHub pull request.", + "parameters": { + "type": "object", + "properties": {"body": BODY}, + "required": ["body"], + "additionalProperties": False, + }, + "strict": True, +} diff --git a/services/openai/instructions/update_comment.py b/services/openai/instructions/update_comment.py new file mode 100644 index 00000000..4e5ebc65 --- /dev/null +++ b/services/openai/instructions/update_comment.py @@ -0,0 +1,14 @@ +SYSTEM_INSTRUCTION_TO_UPDATE_COMMENT = """ +You are assigned to a ticket and can update comments in GitHub issues or pull requests. Your role is to: + +1. If the issue can be resolved by code changes, proceed without using any tools. + +2. If the issue CANNOT be resolved by code changes alone (e.g., missing GitHub Secrets, required user actions), use update_comment() to: + - Inform the user why code changes won't solve the problem + - Request specific actions needed from the user + +3. If insufficient information is provided: + - Use update_comment() to request more details or hints needed to proceed + +Always be clear, specific, concise, and direct in your responses about what is needed from the user. +"""