From 18b76e7ba0be76525cbab40f77308aaf44047175 Mon Sep 17 00:00:00 2001 From: vagrant Date: Thu, 4 Jul 2024 09:23:37 +0000 Subject: [PATCH 01/10] Implementation of ask command --- cmd/main.go | 23 ++++++++++++++++++++++- internal/config/config.yaml | 5 ++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index b88b4f5..92a2d7a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -16,6 +16,7 @@ func main() { repo = flag.String("repo", "", "Repository name") owner = flag.String("owner", "", "Repository owner") issueNumber = flag.Int("issue", 0, "Issue number") + intent = flag.String("intent", "", "Question or intent for the 'ask' command") command = flag.String("command", "", "Command to be executed by AI") configFile = flag.String("config", "./internal/config/config.yaml", "Configuration file") gh_token = flag.String("github-token", "", "GitHub token") @@ -45,10 +46,19 @@ func main() { // Create a GitHub Issues instance. From now on, you can control GitHub from this instance. issue := github.NewIssue(*owner, *repo, *issueNumber, *gh_token) + if issue == nil { + logger.Fatalf("Failed to create GitHub issue instance") + } // Get Issue's information(e.g. Title, Body) and add them to the user prompt except for comments by Actions. title, _ := issue.GetTitle() + if err != nil || title == nil { + logger.Fatalf("Error getting Title: %v", err) + } body, _ := issue.GetBody() + if err != nil || body == nil { + logger.Fatalf("Error getting Body: %v", err) + } if cfg.System.Debug.Log_level == "debug" { logger.Println("Title:", *title) logger.Println("Body:", *body) @@ -58,6 +68,9 @@ func main() { // Get comments under the Issue and add them to the user prompt except for comments by Actions. comments, _ := issue.GetComments() + if err != nil || comments == nil { + logger.Fatalf("Error getting comments: %v", err) + } for _, v := range comments { if *v.User.Login == "github-actions[bot]" { continue @@ -69,7 +82,15 @@ func main() { } // Set system prompt - system_prompt := cfg.Ai.Commands[*command].System_prompt + var system_prompt string + if *command == "ask" { + if *intent == "" { + logger.Fatalf("Error: intent is required for 'ask' command") + } + system_prompt = cfg.Ai.Commands[*command].System_prompt + *intent + } else { + system_prompt = cfg.Ai.Commands[*command].System_prompt + } prompt := ai.Prompt{UserPrompt: user_prompt, SystemPrompt: system_prompt} logger.Println("\x1b[34mPrompt: |\n", prompt.SystemPrompt, prompt.UserPrompt, "\x1b[0m") diff --git a/internal/config/config.yaml b/internal/config/config.yaml index 42aaca0..6a2393c 100644 --- a/internal/config/config.yaml +++ b/internal/config/config.yaml @@ -23,4 +23,7 @@ ai: system_prompt: "The following is the GitHub Issue and comments on it. Please summarize the conversation and suggest what issues need to be resolved.\n" - improve: description: "Improve the GitHub Issues" - system_prompt: "The following is the GitHub Issue and comments on it. Please identify the issues that need to be resolved based on the contents of the Issue and provide three suggestions for improvement." \ No newline at end of file + system_prompt: "The following is the GitHub Issue and comments on it. Please identify the issues that need to be resolved based on the contents of the Issue and provide three suggestions for improvement." + - ask: + description: "Ask a question about the GitHub Issue" + system_prompt: "The following is the GitHub Issue and comments on it. Based on the content provide a detailed response to the following question:\n" \ No newline at end of file From 1f5d390dc3387fe8036040a3944b9598ca87ffa1 Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 9 Jul 2024 01:07:45 +0000 Subject: [PATCH 02/10] Corrected error handling of Issue information retrieval --- cmd/main.go | 11 ++++------- internal/config/config.yaml | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 92a2d7a..b77a243 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -35,9 +35,6 @@ func main() { log.Ldate|log.Ltime|log.Llongfile|log.Lmsgprefix, ) - // Pre-define variables for error handling - var err error - // Get configuration cfg, err := utils.NewConfig(*configFile) if err != nil { @@ -51,12 +48,12 @@ func main() { } // Get Issue's information(e.g. Title, Body) and add them to the user prompt except for comments by Actions. - title, _ := issue.GetTitle() - if err != nil || title == nil { + title, err := issue.GetTitle() + if err != nil { logger.Fatalf("Error getting Title: %v", err) } - body, _ := issue.GetBody() - if err != nil || body == nil { + body, err := issue.GetBody() + if err != nil { logger.Fatalf("Error getting Body: %v", err) } if cfg.System.Debug.Log_level == "debug" { diff --git a/internal/config/config.yaml b/internal/config/config.yaml index 6a2393c..9571dd2 100644 --- a/internal/config/config.yaml +++ b/internal/config/config.yaml @@ -8,7 +8,7 @@ github: repo: "alert-menta" ai: - provider: "vertexai" # "openai" or "vertexai" + provider: "openai" # "openai" or "vertexai" openai: model: "gpt-3.5-turbo" # Check the list of available models by `curl https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY"` From e0fe35eb631592729c91f7a290bad51a7eb979d6 Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 9 Jul 2024 02:05:47 +0000 Subject: [PATCH 03/10] Updated description of argument /command/ --- cmd/main.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/main.go b/cmd/main.go index b77a243..2863992 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -17,7 +17,11 @@ func main() { owner = flag.String("owner", "", "Repository owner") issueNumber = flag.Int("issue", 0, "Issue number") intent = flag.String("intent", "", "Question or intent for the 'ask' command") - command = flag.String("command", "", "Command to be executed by AI") + command = flag.String("command", "", `Command to be executed by AI + describe: Generate a detailed description of the Issue. + analyze: Perform a root cause analysis based on the contents of the Issue. + suggest: Provide suggestions for improvement based on the contents of the Issue. + ask: Answer free-text questions.`) configFile = flag.String("config", "./internal/config/config.yaml", "Configuration file") gh_token = flag.String("github-token", "", "GitHub token") oai_key = flag.String("api-key", "", "OpenAI api key") From ec9505904f877b30366c00b554dfd1b20d93d496 Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 9 Jul 2024 02:40:14 +0000 Subject: [PATCH 04/10] Update error handling when intent argument is empty --- cmd/main.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/main.go b/cmd/main.go index b77a243..8b8f647 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -82,7 +82,10 @@ func main() { var system_prompt string if *command == "ask" { if *intent == "" { - logger.Fatalf("Error: intent is required for 'ask' command") + log.SetOutput(os.Stdout) + logger.Println("Error: intent is required for 'ask' command") + flag.PrintDefaults() + os.Exit(1) } system_prompt = cfg.Ai.Commands[*command].System_prompt + *intent } else { From 57d9139ac8e3012f8c71f3ab8b0b467024d71982 Mon Sep 17 00:00:00 2001 From: vagrant Date: Thu, 11 Jul 2024 08:24:09 +0000 Subject: [PATCH 05/10] Removed analyze description in help --- cmd/main.go | 5 ++--- internal/config/config.yaml | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 2863992..735acc4 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -19,7 +19,6 @@ func main() { intent = flag.String("intent", "", "Question or intent for the 'ask' command") command = flag.String("command", "", `Command to be executed by AI describe: Generate a detailed description of the Issue. - analyze: Perform a root cause analysis based on the contents of the Issue. suggest: Provide suggestions for improvement based on the contents of the Issue. ask: Answer free-text questions.`) configFile = flag.String("config", "./internal/config/config.yaml", "Configuration file") @@ -68,8 +67,8 @@ func main() { user_prompt += "Body:" + *body + "\n" // Get comments under the Issue and add them to the user prompt except for comments by Actions. - comments, _ := issue.GetComments() - if err != nil || comments == nil { + comments, err := issue.GetComments() + if err != nil { logger.Fatalf("Error getting comments: %v", err) } for _, v := range comments { diff --git a/internal/config/config.yaml b/internal/config/config.yaml index 9571dd2..9c18df9 100644 --- a/internal/config/config.yaml +++ b/internal/config/config.yaml @@ -21,9 +21,9 @@ ai: - describe: description: "Describe the GitHub Issues" system_prompt: "The following is the GitHub Issue and comments on it. Please summarize the conversation and suggest what issues need to be resolved.\n" - - improve: + - suggest: description: "Improve the GitHub Issues" - system_prompt: "The following is the GitHub Issue and comments on it. Please identify the issues that need to be resolved based on the contents of the Issue and provide three suggestions for improvement." + system_prompt: "The following is the GitHub Issue and comments on it. Please identify the issues that need to be resolved based on the contents of the Issue and provide three suggestions for improvement.\n" - ask: description: "Ask a question about the GitHub Issue" system_prompt: "The following is the GitHub Issue and comments on it. Based on the content provide a detailed response to the following question:\n" \ No newline at end of file From bb275dec7ad6687b2eddac9f786a7bb781e46696 Mon Sep 17 00:00:00 2001 From: vagrant Date: Thu, 11 Jul 2024 09:38:05 +0000 Subject: [PATCH 06/10] update subcommands --- cmd/main.go | 1 - internal/config/config.yaml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 7bf647d..48d0073 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -85,7 +85,6 @@ func main() { var system_prompt string if *command == "ask" { if *intent == "" { - log.SetOutput(os.Stdout) logger.Println("Error: intent is required for 'ask' command") flag.PrintDefaults() os.Exit(1) diff --git a/internal/config/config.yaml b/internal/config/config.yaml index 9c18df9..52ffb96 100644 --- a/internal/config/config.yaml +++ b/internal/config/config.yaml @@ -20,9 +20,9 @@ ai: commands: - describe: description: "Describe the GitHub Issues" - system_prompt: "The following is the GitHub Issue and comments on it. Please summarize the conversation and suggest what issues need to be resolved.\n" + system_prompt: "The following is the GitHub Issue and comments on it. Please Generate a detailed description.\n" - suggest: - description: "Improve the GitHub Issues" + description: "Provide suggestions for improvement based on the contents of the Issue" system_prompt: "The following is the GitHub Issue and comments on it. Please identify the issues that need to be resolved based on the contents of the Issue and provide three suggestions for improvement.\n" - ask: description: "Ask a question about the GitHub Issue" From b8f14366f30f9f84a7e87f99ea712aeb458d5419 Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 16 Jul 2024 02:01:32 +0000 Subject: [PATCH 07/10] solove conflict --- cmd/main.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index b4b789c..48d0073 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -19,10 +19,6 @@ func main() { intent = flag.String("intent", "", "Question or intent for the 'ask' command") command = flag.String("command", "", `Command to be executed by AI describe: Generate a detailed description of the Issue. -<<<<<<< HEAD - analyze: Perform a root cause analysis based on the contents of the Issue. -======= ->>>>>>> update/subcommands suggest: Provide suggestions for improvement based on the contents of the Issue. ask: Answer free-text questions.`) configFile = flag.String("config", "./internal/config/config.yaml", "Configuration file") From 8f3af78612d85c1014e27e5cc1f72bd46076e399 Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 16 Jul 2024 06:47:13 +0000 Subject: [PATCH 08/10] Removed unused items from the configuration file and added the ability to validate subcommands --- cmd/main.go | 17 ++++++++++++----- internal/config/config.yaml | 11 +++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 48d0073..e10c76f 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,6 +4,7 @@ import ( "flag" "log" "os" + "strings" "github.com/3-shake/alert-menta/internal/ai" "github.com/3-shake/alert-menta/internal/github" @@ -17,10 +18,7 @@ func main() { owner = flag.String("owner", "", "Repository owner") issueNumber = flag.Int("issue", 0, "Issue number") intent = flag.String("intent", "", "Question or intent for the 'ask' command") - command = flag.String("command", "", `Command to be executed by AI - describe: Generate a detailed description of the Issue. - suggest: Provide suggestions for improvement based on the contents of the Issue. - ask: Answer free-text questions.`) + command = flag.String("command", "", "Commands to be executed by AI.Commands defined in the configuration file are available.") configFile = flag.String("config", "./internal/config/config.yaml", "Configuration file") gh_token = flag.String("github-token", "", "GitHub token") oai_key = flag.String("api-key", "", "OpenAI api key") @@ -38,12 +36,21 @@ func main() { log.Ldate|log.Ltime|log.Llongfile|log.Lmsgprefix, ) - // Get configuration + // Load configuration cfg, err := utils.NewConfig(*configFile) if err != nil { logger.Fatalf("Error creating comment: %s", err) } + // Validate command + if _, ok := cfg.Ai.Commands[*command]; !ok { + allowedCommands := make([]string, 0, len(cfg.Ai.Commands)) + for cmd := range cfg.Ai.Commands { + allowedCommands = append(allowedCommands, cmd) + } + logger.Fatalf("Invalid command: %s. Allowed commands are %s.", *command, strings.Join(allowedCommands, ", ")) + } + // Create a GitHub Issues instance. From now on, you can control GitHub from this instance. issue := github.NewIssue(*owner, *repo, *issueNumber, *gh_token) if issue == nil { diff --git a/internal/config/config.yaml b/internal/config/config.yaml index 52ffb96..aa7d1a5 100644 --- a/internal/config/config.yaml +++ b/internal/config/config.yaml @@ -1,12 +1,7 @@ system: debug: - mode: True log_level: debug -github: - owner: "pacificbelt30" - repo: "alert-menta" - ai: provider: "openai" # "openai" or "vertexai" openai: @@ -19,11 +14,11 @@ ai: commands: - describe: - description: "Describe the GitHub Issues" + description: "Generate a detailed description of the Issue." system_prompt: "The following is the GitHub Issue and comments on it. Please Generate a detailed description.\n" - suggest: - description: "Provide suggestions for improvement based on the contents of the Issue" + description: "Provide suggestions for improvement based on the contents of the Issue." system_prompt: "The following is the GitHub Issue and comments on it. Please identify the issues that need to be resolved based on the contents of the Issue and provide three suggestions for improvement.\n" - ask: - description: "Ask a question about the GitHub Issue" + description: "Answer free-text questions." system_prompt: "The following is the GitHub Issue and comments on it. Based on the content provide a detailed response to the following question:\n" \ No newline at end of file From b9957d2e5e8f2c871bd643b529ab6fa9c500d109 Mon Sep 17 00:00:00 2001 From: vagrant Date: Mon, 22 Jul 2024 08:37:37 +0000 Subject: [PATCH 09/10] Change alert-menta.yaml and make the user configuration file mandatory. --- .../config.yaml => .alert-menta.user.yaml | 2 +- .github/workflows/alert-menta.yaml | 54 ++++++++++--------- cmd/main.go | 4 +- 3 files changed, 33 insertions(+), 27 deletions(-) rename internal/config/config.yaml => .alert-menta.user.yaml (97%) diff --git a/internal/config/config.yaml b/.alert-menta.user.yaml similarity index 97% rename from internal/config/config.yaml rename to .alert-menta.user.yaml index aa7d1a5..c03cb38 100644 --- a/internal/config/config.yaml +++ b/.alert-menta.user.yaml @@ -21,4 +21,4 @@ ai: system_prompt: "The following is the GitHub Issue and comments on it. Please identify the issues that need to be resolved based on the contents of the Issue and provide three suggestions for improvement.\n" - ask: description: "Answer free-text questions." - system_prompt: "The following is the GitHub Issue and comments on it. Based on the content provide a detailed response to the following question:\n" \ No newline at end of file + system_prompt: "The following is the GitHub Issue and comments on it. Based on the content provide a detailed response to the following question:\n" diff --git a/.github/workflows/alert-menta.yaml b/.github/workflows/alert-menta.yaml index 338fc18..b935f5d 100644 --- a/.github/workflows/alert-menta.yaml +++ b/.github/workflows/alert-menta.yaml @@ -1,14 +1,14 @@ -name: Reacts to specific labels -run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 +name: "Alert-Menta: Reacts to specific commands" +run-name: LLM responds to issues against the repository.🚀 on: - issues: - types: [labeled] # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issues + issue_comment: + types: [created] jobs: - Issue_Reaction: - if: contains(github.event.issue.labels.*.name, '/describe') || contains(github.event.issue.labels.*.name, '/improve') # https://docs.github.com/ja/webhooks/webhook-events-and-payloads#issues - runs-on: ubuntu-22.04 # https://docs.github.com/ja/actions/using-jobs/choosing-the-runner-for-a-job + Alert-Menta: + if: startsWith(github.event.comment.body, '/describe') || startsWith(github.event.comment.body, '/suggest') || startsWith(github.event.comment.body, '/ask') + runs-on: ubuntu-22.04 permissions: issues: write contents: read @@ -20,31 +20,37 @@ jobs: run: | curl -sLJO -H 'Accept: application/octet-stream' \ "https://${{ secrets.GH_TOKEN }}@api.github.com/repos/3-shake/alert-menta/releases/assets/$( \ - curl -sL "https://${{ secrets.GH_TOKEN }}@api.github.com/repos/3-shake/alert-menta/releases/tags/v0.0.1" \ + curl -sL "https://${{ secrets.GH_TOKEN }}@api.github.com/repos/3-shake/alert-menta/releases/tags/v0.0.3" \ | jq '.assets[] | select(.name | contains("Linux_x86")) | .id')" tar -zxvf alert-menta_Linux_x86_64.tar.gz - - - name: Set Command describe - id: describe - if: contains(github.event.issue.labels.*.name, '/describe') - run: | - echo "COMMAND=describe" >> $GITHUB_ENV - - name: Set Command improve - id: improve - if: steps.describe.conclusion == 'skipped' || contains(github.event.issue.labels.*.name, '/improve') + + - name: Set Command + id: set_command run: | - echo "COMMAND=improve" >> $GITHUB_ENV + COMMENT_BODY="${{ github.event.comment.body }}" + if [[ "$COMMENT_BODY" == /ask* ]]; then + COMMAND=ask + INTENT=${COMMENT_BODY:5} # Get the string following the ask command + echo "INTENT=$INTENT" >> $GITHUB_ENV + elif [[ "$COMMENT_BODY" == /describe* ]]; then + COMMAND=describe + elif [[ "$COMMENT_BODY" == /suggest* ]]; then + COMMAND=suggest + fi + echo "COMMAND=$COMMAND" >> $GITHUB_ENV + - run: echo "REPOSITORY_NAME=${GITHUB_REPOSITORY#${GITHUB_REPOSITORY_OWNER}/}" >> $GITHUB_ENV + - name: Get user defined config file id: user_config if: hashFiles('.alert-menta.user.yaml') != '' run: | - echo "CONFIG_FILE=.alert-menta.user.yaml" >> $GITHUB_ENV - - name: Get default config file - if: steps.user_config.conclusion == 'skipped' && hashFiles('./internal/config/config.yaml') != '' - run: | - echo "CONFIG_FILE=./internal/config/config.yaml" >> $GITHUB_ENV + curl -H "Authorization: token ${{ secrets.GH_TOKEN }}" -L -o .alert-menta.user.yaml "https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ env.REPOSITORY_NAME }}/main/.alert-menta.user.yaml" && echo "CONFIG_FILE=./.alert-menta.user.yaml" >> $GITHUB_ENV - name: Add Comment run: | - ./alert-menta -owner ${{ github.repository_owner }} -issue ${{ github.event.issue.number }} -repo ${{ env.REPOSITORY_NAME }} -github-token ${{ secrets.GITHUB_TOKEN }} -api-key ${{ secrets.OPENAI_API_KEY }} -command $COMMAND -config $CONFIG_FILE + if [[ "$COMMAND" == "ask" ]]; then + ./alert-menta -owner ${{ github.repository_owner }} -issue ${{ github.event.issue.number }} -repo ${{ env.REPOSITORY_NAME }} -github-token ${{ secrets.GH_TOKEN }} -api-key ${{ secrets.OPENAI_API_KEY }} -command $COMMAND -config $CONFIG_FILE -intent $INTENT + else + ./alert-menta -owner ${{ github.repository_owner }} -issue ${{ github.event.issue.number }} -repo ${{ env.REPOSITORY_NAME }} -github-token ${{ secrets.GH_TOKEN }} -api-key ${{ secrets.OPENAI_API_KEY }} -command $COMMAND -config $CONFIG_FILE + fi \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index e10c76f..d9ce845 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -19,13 +19,13 @@ func main() { issueNumber = flag.Int("issue", 0, "Issue number") intent = flag.String("intent", "", "Question or intent for the 'ask' command") command = flag.String("command", "", "Commands to be executed by AI.Commands defined in the configuration file are available.") - configFile = flag.String("config", "./internal/config/config.yaml", "Configuration file") + configFile = flag.String("config", "", "Configuration file") gh_token = flag.String("github-token", "", "GitHub token") oai_key = flag.String("api-key", "", "OpenAI api key") ) flag.Parse() - if *repo == "" || *owner == "" || *issueNumber == 0 || *gh_token == "" || *oai_key == "" || *command == "" { + if *repo == "" || *owner == "" || *issueNumber == 0 || *gh_token == "" || *oai_key == "" || *command == "" || *configFile == "" { flag.PrintDefaults() os.Exit(1) } From 9eef7424d98635d63b2c0cacab54d2a21f487044 Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 23 Jul 2024 01:40:55 +0000 Subject: [PATCH 10/10] update alert-menta.yaml --- .github/workflows/alert-menta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alert-menta.yaml b/.github/workflows/alert-menta.yaml index b935f5d..d42452b 100644 --- a/.github/workflows/alert-menta.yaml +++ b/.github/workflows/alert-menta.yaml @@ -30,7 +30,7 @@ jobs: COMMENT_BODY="${{ github.event.comment.body }}" if [[ "$COMMENT_BODY" == /ask* ]]; then COMMAND=ask - INTENT=${COMMENT_BODY:5} # Get the string following the ask command + INTENT=${COMMENT_BODY:5} echo "INTENT=$INTENT" >> $GITHUB_ENV elif [[ "$COMMENT_BODY" == /describe* ]]; then COMMAND=describe