mirror of
https://github.com/Pull-Pal/pull-pal.git
synced 2024-11-03 01:38:33 -04:00
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:
parent
e648ed50a4
commit
529b720eb6
57
cmd/root.go
57
cmd/root.go
@ -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()
|
log, err := zap.NewProduction()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
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")
|
||||||
|
|
||||||
|
// TODO this loop breaks on the second iteration due to a weird git state or something
|
||||||
|
for {
|
||||||
|
var input string
|
||||||
|
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 issue vc.Issue
|
||||||
var changeRequest llm.CodeChangeRequest
|
var changeRequest llm.CodeChangeRequest
|
||||||
if promptToClipboard {
|
if promptToClipboard {
|
||||||
issue, changeRequest, err = p.PickIssueToClipboard(promptPath)
|
issue, changeRequest, err = p.PickIssueToClipboard(promptPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("error selecting issue and/or generating prompt", zap.Error(err))
|
if !errors.Is(err, pullpal.IssueNotFound) {
|
||||||
|
fmt.Println("error selecting issue and/or generating prompt", err)
|
||||||
return
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Picked issue and copied prompt to clipboard", zap.String("issue ID", issue.ID))
|
|
||||||
} else {
|
} else {
|
||||||
issue, changeRequest, err = p.PickIssueToFile(promptPath)
|
issue, changeRequest, err = p.PickIssueToFile(promptPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("error selecting issue and/or generating prompt", zap.Error(err))
|
if !errors.Is(err, pullpal.IssueNotFound) {
|
||||||
|
fmt.Println("error selecting issue and/or generating prompt", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Info("Picked issue and created prompt", zap.String("issue ID", issue.ID), zap.String("prompt location", promptPath))
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Insert LLM response into response file", zap.String("response location", responsePath))
|
fmt.Printf("\nInsert LLM response into response file: %s", responsePath)
|
||||||
|
|
||||||
var input string
|
fmt.Println("Press 'enter' when ready to parse response. Enter 'skip' to skip response parsing. Enter 'exit' to exit.")
|
||||||
log.Info("Press 'enter' when done.")
|
|
||||||
fmt.Scanln(&input)
|
fmt.Scanln(&input)
|
||||||
|
if input == "exit" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if input == "skip" {
|
||||||
|
fmt.Println()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
prURL, err := p.ProcessResponseFromFile(changeRequest, responsePath)
|
prURL, err := p.ProcessResponseFromFile(changeRequest, responsePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("error parsing LLM response and/or making version control changes", zap.Error(err))
|
fmt.Println("error parsing LLM response and/or making version control changes", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Successfully opened a code change request", zap.String("Github PR link", prURL))
|
fmt.Printf("Successfully opened a code change request. Link: %s\n", prURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Done. Thank you!")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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)
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user