mirror of
https://github.com/Pull-Pal/pull-pal.git
synced 2024-06-11 19:00:45 +00:00
use yaml and make debug files easier
This commit is contained in:
parent
c76d1a3583
commit
322fc8d1da
2
go.mod
2
go.mod
|
@ -11,6 +11,7 @@ require (
|
|||
github.com/stretchr/testify v1.8.1
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/oauth2 v0.7.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -53,5 +54,4 @@ require (
|
|||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
@ -2,8 +2,8 @@ package llm
|
|||
|
||||
// File represents a file in a git repository.
|
||||
type File struct {
|
||||
Path string `json:"path"`
|
||||
Contents string `json:"contents"`
|
||||
Path string `yaml:"path"`
|
||||
Contents string `yaml:"contents"`
|
||||
}
|
||||
|
||||
type ResponseType int
|
||||
|
@ -24,8 +24,8 @@ type CodeChangeRequest struct {
|
|||
|
||||
// CodeChangeResponse contains data derived from an LLM response to a prompt generated via a CodeChangeRequest.
|
||||
type CodeChangeResponse struct {
|
||||
Files []File `json:"files"`
|
||||
Notes string `json:"notes"`
|
||||
Files []File `yaml:"files"`
|
||||
Notes string `yaml:"notes"`
|
||||
}
|
||||
|
||||
// TODO support threads
|
||||
|
@ -37,7 +37,7 @@ type DiffCommentRequest struct {
|
|||
}
|
||||
|
||||
type DiffCommentResponse struct {
|
||||
Type ResponseType `json:"responseType"`
|
||||
Response string `json:"response"`
|
||||
File File `json:"file"`
|
||||
Type ResponseType `yaml:"responseType"`
|
||||
Response string `yaml:"response"`
|
||||
File File `yaml:"file"`
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@ package llm
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"text/template"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func (req DiffCommentRequest) String() string {
|
||||
|
@ -57,6 +58,6 @@ func (res DiffCommentResponse) String() string {
|
|||
|
||||
func ParseDiffCommentResponse(llmResponse string) (DiffCommentResponse, error) {
|
||||
var response DiffCommentResponse
|
||||
err := json.Unmarshal([]byte(llmResponse), &response)
|
||||
err := yaml.Unmarshal([]byte(llmResponse), &response)
|
||||
return response, err
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@ package llm
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"text/template"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// String is the string representation of a CodeChangeRequest. Functionally, it contains the LLM prompt.
|
||||
|
@ -52,6 +53,6 @@ func (res CodeChangeResponse) String() string {
|
|||
// ParseCodeChangeResponse parses the LLM's response to CodeChangeRequest (string) into a CodeChangeResponse.
|
||||
func ParseCodeChangeResponse(llmResponse string) (CodeChangeResponse, error) {
|
||||
var response CodeChangeResponse
|
||||
err := json.Unmarshal([]byte(llmResponse), &response)
|
||||
err := yaml.Unmarshal([]byte(llmResponse), &response)
|
||||
return response, err
|
||||
}
|
||||
|
|
|
@ -52,21 +52,10 @@ func (oc *OpenAIClient) EvaluateCCR(ctx context.Context, model string, req CodeC
|
|||
choice := resp.Choices[0].Message.Content
|
||||
|
||||
oc.log.Info("got response from llm")
|
||||
if oc.debugDir != "" {
|
||||
subdir := path.Join(oc.debugDir, "codechangeresponse")
|
||||
err = os.MkdirAll(subdir, os.ModePerm)
|
||||
if err != nil {
|
||||
oc.log.Error("failed to ensure debug directory existed", zap.String("filepath", subdir), zap.Error(err))
|
||||
} else {
|
||||
fullPath := path.Join(subdir, fmt.Sprintf("%d-%d.json", req.IssueNumber, time.Now().Unix()))
|
||||
err = ioutil.WriteFile(fullPath, []byte(choice), 0644)
|
||||
if err != nil {
|
||||
oc.log.Error("failed to write response to debug file", zap.String("filepath", fullPath), zap.Error(err))
|
||||
} else {
|
||||
oc.log.Info("response written to debug file", zap.String("filepath", fullPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debugFilePrefix := fmt.Sprintf("%d-%d", req.IssueNumber, time.Now().Unix())
|
||||
oc.writeDebug("codechangeresponse", debugFilePrefix+"-req.txt", req.String())
|
||||
oc.writeDebug("codechangeresponse", debugFilePrefix+"-res.yaml", choice)
|
||||
|
||||
return ParseCodeChangeResponse(choice)
|
||||
}
|
||||
|
@ -95,22 +84,32 @@ func (oc *OpenAIClient) EvaluateDiffComment(ctx context.Context, model string, r
|
|||
choice := resp.Choices[0].Message.Content
|
||||
|
||||
oc.log.Info("got response from llm", zap.String("output", choice))
|
||||
// TODO
|
||||
if oc.debugDir != "" {
|
||||
subdir := path.Join(oc.debugDir, "diffcommentresponse")
|
||||
err = os.MkdirAll(subdir, os.ModePerm)
|
||||
if err != nil {
|
||||
oc.log.Error("failed to ensure debug directory existed", zap.String("filepath", subdir), zap.Error(err))
|
||||
} else {
|
||||
fullPath := path.Join(subdir, fmt.Sprintf("%d-%d.json", req.PRNumber, time.Now().Unix()))
|
||||
err = ioutil.WriteFile(fullPath, []byte(choice), 0644)
|
||||
if err != nil {
|
||||
oc.log.Error("failed to write response to debug file", zap.String("filepath", fullPath), zap.Error(err))
|
||||
} else {
|
||||
oc.log.Info("response written to debug file", zap.String("filepath", fullPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debugFilePrefix := fmt.Sprintf("%d-%d", req.PRNumber, time.Now().Unix())
|
||||
oc.writeDebug("diffcommentresponse", debugFilePrefix+"-req.txt", req.String())
|
||||
oc.writeDebug("diffcommentresponse", debugFilePrefix+"-res.yaml", choice)
|
||||
|
||||
return ParseDiffCommentResponse(choice)
|
||||
}
|
||||
|
||||
func (oc *OpenAIClient) writeDebug(subdir, filename, contents string) {
|
||||
if oc.debugDir == "" {
|
||||
return
|
||||
}
|
||||
|
||||
fullFolderPath := path.Join(oc.debugDir, subdir)
|
||||
|
||||
err := os.MkdirAll(fullFolderPath, os.ModePerm)
|
||||
if err != nil {
|
||||
oc.log.Error("failed to ensure debug directory existed", zap.String("folderpath", fullFolderPath), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
fullPath := path.Join(fullFolderPath, filename)
|
||||
err = ioutil.WriteFile(fullPath, []byte(contents), 0644)
|
||||
if err != nil {
|
||||
oc.log.Error("failed to write response to debug file", zap.String("filepath", fullPath), zap.Error(err))
|
||||
return
|
||||
}
|
||||
oc.log.Info("response written to debug file", zap.String("filepath", fullPath))
|
||||
}
|
||||
|
|
|
@ -12,14 +12,13 @@ Subject: {{ .Subject }}
|
|||
Body:
|
||||
{{ .Body }}
|
||||
|
||||
Respond in a parseable JSON format based on the following template:
|
||||
```
|
||||
{
|
||||
"files": [
|
||||
Respond in a parseable YAML format based on the following template. Respond only with YAML, and nothing else:
|
||||
files:
|
||||
{{ range $index, $file := .Files }}
|
||||
{"path": "{{ $file.Path }}", "contents": "[new {{ $file.Path }} contents]"},
|
||||
-
|
||||
path: {{ $file.Path }}
|
||||
contents: |
|
||||
[new {{ $file.Path }} contents]
|
||||
{{ end }}
|
||||
],
|
||||
"notes": "[additional context about your changes]"
|
||||
}
|
||||
```
|
||||
notes: |
|
||||
[additional context about your changes]
|
||||
|
|
|
@ -82,7 +82,7 @@ func NewPullPal(ctx context.Context, log *zap.Logger, cfg Config) (*PullPal, err
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
localGitClient, err := vc.NewLocalGitClient(log.Named("gitclient-"+r), cfg.Self, newRepo)
|
||||
localGitClient, err := vc.NewLocalGitClient(log.Named("gitclient-"+r), cfg.Self, newRepo, cfg.DebugDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -188,11 +188,13 @@ func (p pullPalRepo) checkIssuesAndComments() error {
|
|||
}
|
||||
|
||||
func (p *pullPalRepo) handleIssue(issue vc.Issue) error {
|
||||
err := p.ghClient.CommentOnIssue(issue.Number, "working on it")
|
||||
if err != nil {
|
||||
p.log.Error("error commenting on issue", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
/*
|
||||
err := p.ghClient.CommentOnIssue(issue.Number, "working on it")
|
||||
if err != nil {
|
||||
p.log.Error("error commenting on issue", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
*/
|
||||
for _, label := range p.listIssueOptions.Labels {
|
||||
err = p.ghClient.RemoveLabelFromIssue(issue.Number, label)
|
||||
if err != nil {
|
||||
|
|
|
@ -93,6 +93,7 @@ func ParseIssueBody(body string) IssueBody {
|
|||
issueBody := IssueBody{
|
||||
BaseBranch: "main",
|
||||
}
|
||||
// TODO get rid of parsing like this - "---" may occur in the normal issue body
|
||||
divider := "---"
|
||||
|
||||
parts := strings.Split(body, divider)
|
||||
|
|
43
vc/git.go
43
vc/git.go
|
@ -6,6 +6,7 @@ import (
|
|||
"go/format"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -27,10 +28,11 @@ type LocalGitClient struct {
|
|||
repo Repository
|
||||
|
||||
worktree *git.Worktree
|
||||
debugDir string
|
||||
}
|
||||
|
||||
// NewLocalGitClient initializes a local git client by checking out a repository locally.
|
||||
func NewLocalGitClient(log *zap.Logger, self Author, repo Repository) (*LocalGitClient, error) {
|
||||
func NewLocalGitClient(log *zap.Logger, self Author, repo Repository, debugDir string) (*LocalGitClient, error) {
|
||||
log.Info("checking out local github repo", zap.String("repo name", repo.Name), zap.String("local path", repo.LocalPath))
|
||||
// clone provided repository to local path
|
||||
if repo.LocalPath == "" {
|
||||
|
@ -57,9 +59,10 @@ func NewLocalGitClient(log *zap.Logger, self Author, repo Repository) (*LocalGit
|
|||
repo.localRepo = localRepo
|
||||
|
||||
return &LocalGitClient{
|
||||
log: log,
|
||||
self: self,
|
||||
repo: repo,
|
||||
log: log,
|
||||
self: self,
|
||||
repo: repo,
|
||||
debugDir: debugDir,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -239,6 +242,7 @@ func (gc *LocalGitClient) ParseIssueAndStartCommit(issue Issue) (llm.CodeChangeR
|
|||
}
|
||||
|
||||
issueBody := ParseIssueBody(issue.Body)
|
||||
gc.log.Info("issue body info", zap.Any("files", issueBody.FilePaths))
|
||||
|
||||
// start a worktree
|
||||
err := gc.StartCommit()
|
||||
|
@ -264,11 +268,38 @@ func (gc *LocalGitClient) ParseIssueAndStartCommit(issue Issue) (llm.CodeChangeR
|
|||
files = append(files, nextFile)
|
||||
}
|
||||
|
||||
return llm.CodeChangeRequest{
|
||||
req := llm.CodeChangeRequest{
|
||||
Subject: issue.Subject,
|
||||
Body: issueBody.PromptBody,
|
||||
IssueNumber: issue.Number,
|
||||
Files: files,
|
||||
BaseBranch: issueBody.BaseBranch,
|
||||
}, nil
|
||||
}
|
||||
debugFileNamePrefix := fmt.Sprintf("issue-%d-%d", issue.Number, time.Now().Unix())
|
||||
gc.writeDebug("issues", debugFileNamePrefix+"-originalbody.txt", issue.Body)
|
||||
gc.writeDebug("issues", debugFileNamePrefix+"-parsed-req.txt", req.String())
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (gc *LocalGitClient) writeDebug(subdir, filename, contents string) {
|
||||
if gc.debugDir == "" {
|
||||
return
|
||||
}
|
||||
|
||||
fullFolderPath := path.Join(gc.debugDir, subdir)
|
||||
|
||||
err := os.MkdirAll(fullFolderPath, os.ModePerm)
|
||||
if err != nil {
|
||||
gc.log.Error("failed to ensure debug directory existed", zap.String("folderpath", fullFolderPath), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
fullPath := path.Join(fullFolderPath, filename)
|
||||
err = ioutil.WriteFile(fullPath, []byte(contents), 0644)
|
||||
if err != nil {
|
||||
gc.log.Error("failed to write response to debug file", zap.String("filepath", fullPath), zap.Error(err))
|
||||
return
|
||||
}
|
||||
gc.log.Info("response written to debug file", zap.String("filepath", fullPath))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user