feat(pierre): add diff chunking and configurable review settings #2

Open
schreifuchs wants to merge 4 commits from feat/context-improvements into main
8 changed files with 293 additions and 27 deletions
Showing only changes of commit cc321be658 - Show all commits
View File
+13 -1
View File
@@ -37,7 +37,19 @@ type LLMConfig struct {
Model string `help:"Model to use" env:"LLM_MODEL"`
}
// ReviewConfig holds the reviewspecific CLI options.
// The `default:"60000"` tag sets an integer default of 60KB Kong parses the string value into the int field, which can be confusing for readers.
type ReviewConfig struct {
MaxChunkSize int `help:"Maximum diff chunk size in bytes" default:"60000"`
Guidelines []string `help:"Project guidelines to prepend" sep:","`
DisableComments bool `help:"Disable posting comments (dry run)"`
}
type Config struct {
// Embedding ReviewConfig with a prefix changes flag names to `--review-…`.
// Existing configuration files using the old flag names will need to be updated.
// Consider keeping backwards compatibility if required.
Review ReviewConfig `embed:"" prefix:"review-"`
GitProvider string `help:"Git provider (bitbucket or gitea)" env:"GIT_PROVIDER"`
schreifuchs marked this conversation as resolved Outdated
Outdated
Review

cfg.Review.MaxChunkChars is an int that may be zero if the user omits the flag. The service correctly falls back to the default (60000) inside judgePR, but you could also enforce the default earlier (e.g. in the config struct default tag or after flag parsing) to avoid passing a zero value downstream. (Generated by: OpenAI (openai/gpt-oss-120b))

`cfg.Review.MaxChunkChars` is an `int` that may be zero if the user omits the flag. The service correctly falls back to the default (60000) inside `judgePR`, but you could also enforce the default earlier (e.g. in the config struct default tag or after flag parsing) to avoid passing a zero value downstream. (Generated by: OpenAI (openai/gpt-oss-120b))
Bitbucket BitbucketConfig `embed:"" prefix:"bitbucket-"`
Gitea GiteaConfig `embed:"" prefix:"gitea-"`
@@ -117,7 +129,7 @@ func main() {
log.Fatalf("Error initializing AI: %v", err)
}
pierreService := pierre.New(ai, git)
pierreService := pierre.New(ai, git, cfg.Review.MaxChunkSize, cfg.Review.Guidelines, cfg.Review.DisableComments)
if err := pierreService.MakeReview(context.Background(), cfg.Repo.Owner, cfg.Repo.Repo, cfg.Repo.PRID); err != nil {
log.Fatalf("Error during review: %v", err)
}
+2 -1
View File
@@ -7,7 +7,9 @@ require (
github.com/alecthomas/kong v1.14.0
github.com/alecthomas/kong-yaml v0.2.0
github.com/google/generative-ai-go v0.20.1
schreifuchs marked this conversation as resolved
Review

You added github.com/google/go-cmp v0.7.0 as a direct dependency – good for the new tests. Remember to run go mod tidy so that the go.sum is updated accordingly. (Generated by: OpenAI (openai/gpt-oss-120b))

You added `github.com/google/go-cmp v0.7.0` as a direct dependency – good for the new tests. Remember to run `go mod tidy` so that the `go.sum` is updated accordingly. (Generated by: OpenAI (openai/gpt-oss-120b))
github.com/google/go-cmp v0.7.0
github.com/ollama/ollama v0.16.0
github.com/sashabaranov/go-openai v1.41.2
google.golang.org/api v0.186.0
)
@@ -34,7 +36,6 @@ require (
github.com/googleapis/gax-go/v2 v2.12.5 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/sashabaranov/go-openai v1.41.2 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
+1 -1
View File
1
@@ -31,7 +31,7 @@ func (b *BitbucketAdapter) GetDiff(ctx context.Context, projectKey, repositorySl
if response.StatusCode != http.StatusOK {
sb := &strings.Builder{}
io.Copy(sb, response.Body)
err = fmt.Errorf("error while fetching bitbucket diff staus %d, body %s", response.Status, sb.String())
err = fmt.Errorf("error while fetching bitbucket diff status %d, body %s", response.StatusCode, sb.String())
}
diff = response.Body
+119 -15
View File
@@ -4,10 +4,14 @@ import (
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
"context"
"fmt"
"io"
"strings"
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
"git.schreifuchs.ch/schreifuchs/pierre-bot/internal/chatter"
)
// DefaultChunkSize is the fallback maximum size (in bytes) for a diff chunk when no explicit value is configured.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
const DefaultChunkSize = 60000
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
type Comment struct {
File string `json:"file"`
Line int `json:"line"`
@@ -19,21 +23,121 @@ func (s *Service) judgePR(ctx context.Context, diff io.Reader) (comments []Comme
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if err != nil {
return nil, fmt.Errorf("failed to read diff: %w", err)
}
err = s.chat.GenerateStructured(ctx, []chatter.Message{
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
{
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Role: chatter.RoleSystem,
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Content: `
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
You are a very strict senior software architect.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
You review **only** newly added or modified lines in a unified diff, together with the immediate hunk context.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
You do **not** report issues that appear **solely** in deleted lines (“-”) or that have already been fixed by the change.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
No comments are made on pure formatting/whitespace changes or reordering that does not alter the programs behavior.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
`,
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
},
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
{
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Role: chatter.RoleUser,
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Content: fmt.Sprintf("Hello please review my PR. Write comments where improvements are necessary in new lines.\n Here is the git diff of it: %s", string(diffBytes)),
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
},
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}, &comments)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Determine chunk size (use default if not set)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
maxSize := s.maxChunkSize
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if maxSize <= 0 {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
maxSize = DefaultChunkSize // default 60KB ~ 15k tokens
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
chunks := splitDiffIntoChunks(diffBytes, maxSize)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
allComments := []Comment{}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Build optional guidelines text (added as a separate section with a clear delimiter)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
guidelinesText := ""
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if len(s.guidelines) > 0 {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Two newlines ensure the guidelines start on a fresh paragraph.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
guidelinesText = "\n\nProject guidelines:\n"
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
for _, g := range s.guidelines {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
guidelinesText += "- " + g + "\n"
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// System prompt that instructs the LLM precisely.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
baseSystem := strings.TrimSpace(`
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
You are a strict senior software architect.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Only comment on newly added or modified lines in the diff; ignore deletions, pure formatting, or reordering that does not change behavior.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
For each issue output a JSON object with fields "file", "line", and "message" (message should be concise, ≤2 sentences, and actionable).
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
If project guidelines are provided, treat them as hard rules that must be respected.`) + guidelinesText
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
for i, chunk := range chunks {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Include the chunk identifier in the system message only if there are multiple chunks.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
systemContent := baseSystem
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if len(chunks) > 1 {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
systemContent = fmt.Sprintf("%s\nChunk %d of %d.", baseSystem, i+1, len(chunks))
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
userContent := chunk
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
var chunkComments []Comment
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
err = s.chat.GenerateStructured(ctx, []chatter.Message{{
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Role: chatter.RoleSystem,
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Content: systemContent,
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}, {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Role: chatter.RoleUser,
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Content: userContent,
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}}, &chunkComments)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if err != nil {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
return nil, err
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
allComments = append(allComments, chunkComments...)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Deduplicate comments (keyed by file:line)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
unique := make(map[string]Comment)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
for _, c := range allComments {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
key := fmt.Sprintf("%s:%d", c.File, c.Line)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
unique[key] = c
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
for _, v := range unique {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
comments = append(comments, v)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
schreifuchs marked this conversation as resolved Outdated
Outdated
Review

The comment that builds baseSystem concatenates the dynamically created guidelinesText directly inside a raw string literal. This makes the final prompt contain a leading tab on every line, which the LLM will treat as part of the instruction. Consider using a plain string without the leading indentation or run strings.TrimSpace on the final prompt. (Generated by: OpenAI (openai/gpt-oss-120b))

The comment that builds `baseSystem` concatenates the dynamically created `guidelinesText` directly inside a raw string literal. This makes the final prompt contain a leading tab on every line, which the LLM will treat as part of the instruction. Consider using a plain string without the leading indentation or run `strings.TrimSpace` on the final prompt. (Generated by: OpenAI (openai/gpt-oss-120b))
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
return
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// splitDiffIntoChunks splits a diff into chunks that do not exceed maxSize bytes.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// It tries to split on file boundaries ("diff --git") first, then on hunk boundaries (@@),
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// and finally on a hard byte limit.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
func splitDiffIntoChunks(diff []byte, maxSize int) []string {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if len(diff) <= maxSize {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
return []string{string(diff)}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
content := string(diff)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Split by file headers
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
parts := strings.Split(content, "\ndiff --git ")
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
chunks := []string{}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
var current strings.Builder
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
for idx, part := range parts {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
seg := part
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if idx != 0 {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Preserve the leading newline that was removed by Split
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
seg = "\n" + "diff --git " + part
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if current.Len()+len(seg) > maxSize && current.Len() > 0 {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
chunks = append(chunks, current.String())
schreifuchs marked this conversation as resolved Outdated
Outdated
Review

The splitDiffIntoChunks implementation drops the newline that separates two files when it splits on "\ndiff --git ". After the split the code re‑adds the prefix with "diff --git " + part, which loses the leading line‑break. When the chunks are concatenated the original diff is no longer identical, causing the TestSplitDiffIntoChunks_LargeSingleFile test to fail. Fix by adding the missing newline, e.g. seg = "\n" + "diff --git " + part (or keep the delimiter when splitting with strings.SplitAfter). (Generated by: OpenAI (openai/gpt-oss-120b))

The `splitDiffIntoChunks` implementation drops the newline that separates two files when it splits on `"\ndiff --git "`. After the split the code re‑adds the prefix with `"diff --git " + part`, which loses the leading line‑break. When the chunks are concatenated the original diff is no longer identical, causing the `TestSplitDiffIntoChunks_LargeSingleFile` test to fail. Fix by adding the missing newline, e.g. `seg = "\n" + "diff --git " + part` (or keep the delimiter when splitting with `strings.SplitAfter`). (Generated by: OpenAI (openai/gpt-oss-120b))
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
current.Reset()
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if len(seg) > maxSize {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Split further by hunks
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
hunks := strings.Split(seg, "\n@@ ")
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
for j, h := range hunks {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
var hseg string
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if j == 0 {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// First hunk segment already contains the preceding content (including any needed newline)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
hseg = h
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
} else {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
// Subsequent hunks need the leading newline and "@@ " marker restored
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
hseg = "\n@@ " + h
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if current.Len()+len(hseg) > maxSize && current.Len() > 0 {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
chunks = append(chunks, current.String())
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
current.Reset()
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
schreifuchs marked this conversation as resolved Outdated
Outdated
Review

splitDiffIntoChunks may split a diff in the middle of a line (e.g. when a single line exceeds maxSize). Breaking a diff line arbitrarily can corrupt the unified‑diff syntax and confuse the model. Prefer to split only on line boundaries – e.g. split the input with strings.SplitAfter(diff, "\n") and then build chunks while staying under the size limit. (Generated by: OpenAI (openai/gpt-oss-120b))

`splitDiffIntoChunks` may split a diff in the middle of a line (e.g. when a single line exceeds `maxSize`). Breaking a diff line arbitrarily can corrupt the unified‑diff syntax and confuse the model. Prefer to split only on line boundaries – e.g. split the input with `strings.SplitAfter(diff, "\n")` and then build chunks while staying under the size limit. (Generated by: OpenAI (openai/gpt-oss-120b))
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if len(hseg) > maxSize {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
for len(hseg) > maxSize {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
chunks = append(chunks, hseg[:maxSize])
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
hseg = hseg[maxSize:]
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
current.WriteString(hseg)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
} else {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
current.WriteString(hseg)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
} else {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
current.WriteString(seg)
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
if current.Len() > 0 {
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
chunks = append(chunks, current.String())
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
return chunks
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
}
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
Review

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.

Reading the entire diff into memory using io.ReadAll(diff) can cause excessive memory usage if a pull request has a very large diff; consider streaming or limiting the read size.
+132
View File
@@ -0,0 +1,132 @@
package pierre
import (
"bytes"
"context"
"io"
"strings"
"testing"
"git.schreifuchs.ch/schreifuchs/pierre-bot/internal/chatter"
"github.com/google/go-cmp/cmp"
)
// mockChat implements the ChatAdapter interface for testing.
type mockChat struct{ callCount int }
func (m *mockChat) GenerateStructured(ctx context.Context, msgs []chatter.Message, target interface{}) error {
m.callCount++
if cSlice, ok := target.(*[]Comment); ok {
*cSlice = []Comment{{File: "file.go", Line: 1, Message: "test comment"}}
return nil
}
return nil
}
func (m *mockChat) GetProviderName() string { return "mock" }
// mockGit implements the GitAdapter interface for testing.
type mockGit struct{}
func (g *mockGit) GetDiff(ctx context.Context, owner, repo string, prID int) (io.ReadCloser, error) {
diff := "diff --git a/file1.go b/file1.go\n+line1\n" + "diff --git a/file2.go b/file2.go\n+line2\n"
return io.NopCloser(bytes.NewReader([]byte(diff))), nil
schreifuchs marked this conversation as resolved Outdated
Outdated
Review

The test TestSplitDiffIntoChunks_LargeSingleFile relies on an exact string equality after re‑joining the chunks. Because of the newline‑loss bug described above the test will currently fail. Once the split function preserves delimiters, the test will pass; otherwise consider comparing the recombined diff with the original using cmp.Diff only (as you already do) rather than a strict equality check. (Generated by: OpenAI (openai/gpt-oss-120b))

The test `TestSplitDiffIntoChunks_LargeSingleFile` relies on an exact string equality after re‑joining the chunks. Because of the newline‑loss bug described above the test will currently fail. Once the split function preserves delimiters, the test will pass; otherwise consider comparing the recombined diff with the original using `cmp.Diff` only (as you already do) rather than a strict equality check. (Generated by: OpenAI (openai/gpt-oss-120b))
}
func (g *mockGit) AddComment(ctx context.Context, owner, repo string, prID int, comment Comment) error {
return nil
}
func TestSplitDiffIntoChunks(t *testing.T) {
cases := []struct {
name string
diff string
maxSize int
wantChunks int // 0 means we don't assert exact count
wantPrefixes []string
checkRecombine bool
}{
{
name: "small diff",
diff: "diff --git a/file1.txt b/file1.txt\n+added line\n",
maxSize: 1000,
wantChunks: 1,
wantPrefixes: []string{"diff --git a/file1.txt"},
checkRecombine: true,
},
{
name: "multiple files",
diff: "diff --git a/file1.txt b/file1.txt\n+added line 1\n" +
"diff --git a/file2.txt b/file2.txt\n+added line 2\n",
maxSize: 50,
wantChunks: 2,
wantPrefixes: []string{"diff --git a/file1.txt", "diff --git a/file2.txt"},
checkRecombine: false,
},
{
name: "large single file",
diff: func() string {
line := "+very long added line that will be repeated many times to exceed the chunk size\n"
return "diff --git a/large.txt b/large.txt\n" + strings.Repeat(line, 200)
}(),
maxSize: 500,
wantChunks: 0,
wantPrefixes: nil,
checkRecombine: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
chunks := splitDiffIntoChunks([]byte(tc.diff), tc.maxSize)
if tc.wantChunks > 0 && len(chunks) != tc.wantChunks {
t.Fatalf("expected %d chunks, got %d", tc.wantChunks, len(chunks))
}
for i, prefix := range tc.wantPrefixes {
if i >= len(chunks) {
t.Fatalf("missing chunk %d for prefix check", i)
}
trimmed := strings.TrimPrefix(chunks[i], "\n")
if !strings.HasPrefix(trimmed, prefix) {
t.Fatalf("chunk %d does not start with expected prefix %q: %s", i, prefix, chunks[i])
}
}
for i, c := range chunks {
if tc.maxSize > 0 && len(c) > tc.maxSize {
t.Fatalf("chunk %d exceeds max size %d: %d", i, tc.maxSize, len(c))
}
}
if tc.checkRecombine {
recombined := strings.Join(chunks, "")
if diff := cmp.Diff(tc.diff, recombined); diff != "" {
t.Fatalf("recombined diff differs:\n%s", diff)
}
}
})
}
}
func TestJudgePR_ChunkAggregationAndDeduplication(t *testing.T) {
chatMock := &mockChat{}
svc := &Service{
maxChunkSize: 50,
guidelines: nil,
git: &mockGit{},
chat: chatMock,
}
diffReader, err := svc.git.GetDiff(context.Background(), "", "", 0)
if err != nil {
t.Fatalf("failed to get diff: %v", err)
}
defer diffReader.Close()
comments, err := svc.judgePR(context.Background(), diffReader)
if err != nil {
t.Fatalf("judgePR error: %v", err)
}
if got, want := len(comments), 1; got != want {
t.Fatalf("expected %d comment after deduplication, got %d", want, got)
}
if chatMock.callCount != 2 {
t.Fatalf("expected mockChat to be called for each chunk (2), got %d", chatMock.callCount)
}
}
+16 -5
View File
@@ -7,15 +7,26 @@ import (
"git.schreifuchs.ch/schreifuchs/pierre-bot/internal/chatter"
)
// Service holds the core collaborators and configuration for Pierre.
// The order of the fields is intentional: configuration fields first (used
// during initialization) followed by the adapters. This prevents accidental
// changes to the serialized layout if encoding/gob or encoding/json is used
// elsewhere in the future.
schreifuchs marked this conversation as resolved Outdated
Outdated
Review

New now takes the extra parameters maxChunkSize and guidelines. Ensure all call‑sites (currently only cmd/pierre/main.go) are updated accordingly. Consider adding a comment that documents the meaning of maxChunkSize (bytes) and that a non‑positive value triggers the built‑in default. (Generated by: OpenAI (openai/gpt-oss-120b))

`New` now takes the extra parameters `maxChunkSize` and `guidelines`. Ensure all call‑sites (currently only `cmd/pierre/main.go`) are updated accordingly. Consider adding a comment that documents the meaning of `maxChunkSize` (bytes) and that a non‑positive value triggers the built‑in default. (Generated by: OpenAI (openai/gpt-oss-120b))
type Service struct {
git GitAdapter
chat ChatAdapter
maxChunkSize int
guidelines []string
disableComments bool
git GitAdapter
chat ChatAdapter
}
func New(chat ChatAdapter, git GitAdapter) *Service {
func New(chat ChatAdapter, git GitAdapter, maxChunkSize int, guidelines []string, disableComments bool) *Service {
return &Service{
git: git,
chat: chat,
git: git,
chat: chat,
maxChunkSize: maxChunkSize,
guidelines: guidelines,
disableComments: disableComments,
}
}
+10 -4
View File
@@ -26,11 +26,17 @@ func (s *Service) MakeReview(ctx context.Context, organisation string, repo stri
for _, c := range comments {
c.Message = fmt.Sprintf("%s (Generated by: %s)", c.Message, model)
fmt.Printf("File: %s\nLine: %d\nMessage: %s\n%s\n",
c.File, c.Line, c.Message, "---")
schreifuchs marked this conversation as resolved Outdated
Outdated
Review

The condition for posting comments is inverted; it adds comments when disableComments is true. Change if s.disableComments { to if !s.disableComments {. (Reason: The code adds VCS comments only when s.disableComments is true, which contradicts the flag's purpose; flipping the condition fixes the logic.) (Generated by: OpenAI (openai/gpt-oss-120b))

The condition for posting comments is inverted; it adds comments when `disableComments` is true. Change `if s.disableComments {` to `if !s.disableComments {`. (Reason: The code adds VCS comments only when `s.disableComments` is true, which contradicts the flag's purpose; flipping the condition fixes the logic.) (Generated by: OpenAI (openai/gpt-oss-120b))
if err := s.git.AddComment(ctx, organisation, repo, prID, c); err != nil {
log.Printf("Failed to add comment: %v", err)
if s.disableComments {
// Dryrun: just log what would have been posted.
log.Printf("dryrun: %s:%d => %s", c.File, c.Line, c.Message)
} else {
schreifuchs marked this conversation as resolved
Review

Update the comment above the block to reflect that comments are posted only when not in dry‑run mode. (Reason: The comment correctly identifies that the existing comment is misleading—the code posts comments only when disableComments (dry‑run) is true, so the comment should be updated to reflect posting occurs when not in dry‑run mode.) (Generated by: OpenAI (openai/gpt-oss-120b))

Update the comment above the block to reflect that comments are posted only when not in dry‑run mode. (Reason: The comment correctly identifies that the existing comment is misleading—the code posts comments only when `disableComments` (dry‑run) is true, so the comment should be updated to reflect posting occurs when not in dry‑run mode.) (Generated by: OpenAI (openai/gpt-oss-120b))
// Normal mode: print to stdout and post the comment to the VCS.
fmt.Printf("File: %s\nLine: %d\nMessage: %s\n%s\n",
c.File, c.Line, c.Message, "---")
if err := s.git.AddComment(ctx, organisation, repo, prID, c); err != nil {
log.Printf("Failed to add comment: %v", err)
}
}
}