Loop prompt generation/response parsing

Alternate between generating prompts via Github issues and parsing LLM
responses until the user exits.

Also slightly modify LLM response parsing to handle some unintentional
text which is copied from ChatGPT's web UI for code blocks.
This commit is contained in:
Moby von Briesen 2023-04-22 22:44:44 -04:00
parent e648ed50a4
commit 529b720eb6
2 changed files with 67 additions and 36 deletions

View File

@ -1,6 +1,7 @@
package cmd package cmd
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
@ -36,10 +37,14 @@ It can be used to:
promptToClipboard := viper.GetBool("prompt-to-clipboard") promptToClipboard := viper.GetBool("prompt-to-clipboard")
responsePath := viper.GetString("response-path") responsePath := viper.GetString("response-path")
log, err := zap.NewProduction() /*
if err != nil { log, err := zap.NewProduction()
panic(err) if err != nil {
} panic(err)
}
*/
log := zap.L()
author := vc.Author{ author := vc.Author{
Email: selfEmail, Email: selfEmail,
@ -56,43 +61,69 @@ It can be used to:
} }
p, err := pullpal.NewPullPal(cmd.Context(), log.Named("pullpal"), author, repo) p, err := pullpal.NewPullPal(cmd.Context(), log.Named("pullpal"), author, repo)
if err != nil { if err != nil {
log.Error("error creating new pull pal", zap.Error(err)) fmt.Println("error creating new pull pal", err)
return return
} }
log.Info("Successfully initialized pull pal") fmt.Println("Successfully initialized pull pal")
var issue vc.Issue // TODO this loop breaks on the second iteration due to a weird git state or something
var changeRequest llm.CodeChangeRequest for {
if promptToClipboard { var input string
issue, changeRequest, err = p.PickIssueToClipboard(promptPath) fmt.Println("Press 'enter' when ready to select issue. Type 'exit' to exit.")
fmt.Scanln(&input)
if input == "exit" {
break
}
var issue vc.Issue
var changeRequest llm.CodeChangeRequest
if promptToClipboard {
issue, changeRequest, err = p.PickIssueToClipboard(promptPath)
if err != nil {
if !errors.Is(err, pullpal.IssueNotFound) {
fmt.Println("error selecting issue and/or generating prompt", err)
return
} else {
fmt.Println("No issues found. Proceeding to parse prompt")
}
} else {
fmt.Printf("Picked issue and copied prompt to clipboard. Issue #%s\n", issue.ID)
}
} else {
issue, changeRequest, err = p.PickIssueToFile(promptPath)
if err != nil {
if !errors.Is(err, pullpal.IssueNotFound) {
fmt.Println("error selecting issue and/or generating prompt", err)
return
}
fmt.Println("No issues found. Proceeding to parse prompt")
} else {
fmt.Printf("Picked issue and copied prompt to clipboard. Issue #%s. Prompt location %s\n", issue.ID, promptPath)
}
}
fmt.Printf("\nInsert LLM response into response file: %s", responsePath)
fmt.Println("Press 'enter' when ready to parse response. Enter 'skip' to skip response parsing. Enter 'exit' to exit.")
fmt.Scanln(&input)
if input == "exit" {
break
}
if input == "skip" {
fmt.Println()
continue
}
prURL, err := p.ProcessResponseFromFile(changeRequest, responsePath)
if err != nil { if err != nil {
log.Error("error selecting issue and/or generating prompt", zap.Error(err)) fmt.Println("error parsing LLM response and/or making version control changes", err)
return return
} }
log.Info("Picked issue and copied prompt to clipboard", zap.String("issue ID", issue.ID)) fmt.Printf("Successfully opened a code change request. Link: %s\n", prURL)
} else {
issue, changeRequest, err = p.PickIssueToFile(promptPath)
if err != nil {
log.Error("error selecting issue and/or generating prompt", zap.Error(err))
return
}
log.Info("Picked issue and created prompt", zap.String("issue ID", issue.ID), zap.String("prompt location", promptPath))
} }
log.Info("Insert LLM response into response file", zap.String("response location", responsePath)) fmt.Println("Done. Thank you!")
var input string
log.Info("Press 'enter' when done.")
fmt.Scanln(&input)
prURL, err := p.ProcessResponseFromFile(changeRequest, responsePath)
if err != nil {
log.Error("error parsing LLM response and/or making version control changes", zap.Error(err))
return
}
log.Info("Successfully opened a code change request", zap.String("Github PR link", prURL))
}, },
} }
@ -137,13 +168,11 @@ func init() {
} }
func initConfig() { func initConfig() {
fmt.Println("init")
if cfgFile != "" { if cfgFile != "" {
fmt.Println("cfg file exists") fmt.Println("cfg file exists")
// Use config file from the flag. // Use config file from the flag.
viper.SetConfigFile(cfgFile) viper.SetConfigFile(cfgFile)
} else { } else {
fmt.Println("cfg file empty")
// Find home directory. // Find home directory.
home, err := os.UserHomeDir() home, err := os.UserHomeDir()
cobra.CheckErr(err) cobra.CheckErr(err)

View File

@ -95,8 +95,10 @@ func parseFiles(filesSection string) []File {
for i, f := range fileStringList { for i, f := range fileStringList {
fileParts := strings.Split(f, "contents:") fileParts := strings.Split(f, "contents:")
path := strings.TrimSpace(fileParts[0]) path := strings.TrimSpace(fileParts[0])
contents := strings.TrimSpace(fileParts[1]) // TODO currently, copy-pasting code from chatgpt also copies some additional text
contents = strings.Trim(contents, "```") // the following separates this unintended section from the actual intended contents of the file
contentParts := strings.Split(fileParts[1], "Copy code")
contents := strings.TrimSpace(contentParts[1])
fileList[i] = File{ fileList[i] = File{
Path: path, Path: path,