package review import ( "fmt" "strings" ) // BuildSystemPrompt constructs the system prompt for the LLM reviewer. func BuildSystemPrompt(conventions string) string { var sb strings.Builder sb.WriteString("You are an expert code reviewer. Review the provided pull request diff carefully.\n\n") sb.WriteString("Your task:\n") sb.WriteString("1. Review the diff for correctness, idiomatic code, potential bugs, and design issues.\n") sb.WriteString("2. Consider the CI status — if CI has failed, that is an automatic REQUEST_CHANGES regardless of code quality.\n") sb.WriteString("3. Output your review as structured JSON (and ONLY JSON, no markdown fences or other text).\n\n") sb.WriteString("Output format:\n") sb.WriteString("{\n") sb.WriteString(" \"verdict\": \"APPROVE\" or \"REQUEST_CHANGES\",\n") sb.WriteString(" \"summary\": \"Brief overall assessment (1-3 sentences)\",\n") sb.WriteString(" \"findings\": [\n") sb.WriteString(" {\n") sb.WriteString(" \"severity\": \"MAJOR\" or \"MINOR\" or \"NIT\",\n") sb.WriteString(" \"file\": \"path/to/file\",\n") sb.WriteString(" \"line\": ,\n") sb.WriteString(" \"finding\": \"Description of the issue\"\n") sb.WriteString(" }\n") sb.WriteString(" ],\n") sb.WriteString(" \"recommendation\": \"Full recommendation text explaining your verdict\"\n") sb.WriteString("}\n\n") sb.WriteString("Rules:\n") sb.WriteString("- If there are any MAJOR findings → verdict must be REQUEST_CHANGES\n") sb.WriteString("- If there are no MAJOR findings → verdict should be APPROVE\n") sb.WriteString("- If CI has failed → verdict must be REQUEST_CHANGES with a finding noting the CI failure\n") sb.WriteString("- Be thorough but fair. Don't nitpick style unless it impacts readability significantly.\n") sb.WriteString("- Line numbers should reference the new file line numbers from the diff headers.\n") sb.WriteString("- If the diff is empty or trivial (only formatting/whitespace), APPROVE with no findings.\n") if conventions != "" { sb.WriteString(fmt.Sprintf("\n\nThe repository has the following coding conventions that should be respected:\n\n%s\n", conventions)) } return sb.String() } // BuildUserPrompt constructs the user message with PR context. func BuildUserPrompt(title, description, diff string, ciPassed bool, ciDetails string) string { var sb strings.Builder sb.WriteString(fmt.Sprintf("## Pull Request: %s\n\n", title)) if description != "" { sb.WriteString(fmt.Sprintf("### Description\n%s\n\n", description)) } ciStatus := "PASSED" if !ciPassed { ciStatus = "FAILED" } sb.WriteString(fmt.Sprintf("### CI Status: %s\n", ciStatus)) if ciDetails != "" { sb.WriteString(fmt.Sprintf("CI Details: %s\n", ciDetails)) } sb.WriteString("\n### Diff\n\n") sb.WriteString("```diff\n") sb.WriteString(diff) sb.WriteString("\n```\n") return sb.String() }