Skip to content

Commit 6a6869f

Browse files
anakrishCopilot
andcommitted
improve: better line anchoring with code content in prompt
Include actual code content with each anchor line so the LLM can match findings to specific changed lines. Mark added vs context lines and instruct the model to prefer added lines. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 00e53aa commit 6a6869f

1 file changed

Lines changed: 67 additions & 31 deletions

File tree

.github/scripts/perspective-review.sh

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,37 +33,42 @@ gh api "repos/${REPO}/pulls/${PR_NUMBER}" \
3333
| head -c 60000 > /tmp/pr_diff.txt
3434
echo "Diff size: $(wc -c < /tmp/pr_diff.txt) bytes"
3535

36-
# Parse diff to extract valid RIGHT-side line numbers per file.
37-
# These are the only lines the PR Review API will accept for inline comments.
36+
# Parse diff to extract valid RIGHT-side line anchors with code content.
37+
# Format: file:line:type:code (type is "added" for + lines, "context" for unchanged)
3838
echo "Extracting valid line anchors from diff..."
3939
awk '
40-
/^diff --git/ {
41-
# Extract filename from +++ line (next after ---)
42-
file = ""
43-
}
44-
/^\+\+\+ b\// {
45-
file = substr($0, 7) # strip "+++ b/"
46-
}
40+
/^diff --git/ { file = "" }
41+
/^\+\+\+ b\// { file = substr($0, 7) }
4742
/^@@ / {
48-
# Parse new-file line number from @@ -old,len +new,len @@
4943
match($0, /\+([0-9]+)(,([0-9]+))?/, arr)
5044
start = arr[1] + 0
51-
count = (arr[3] != "") ? arr[3] + 0 : 1
5245
line = start
5346
}
5447
file != "" && !/^diff --git/ && !/^---/ && !/^\+\+\+/ && !/^@@/ {
5548
if (/^-/) {
56-
# Deleted line: not on RIGHT side, skip
49+
# Deleted line: skip (not on RIGHT side)
50+
} else if (/^\+/) {
51+
# Added line
52+
code = substr($0, 2) # strip leading +
53+
gsub(/\t/, " ", code)
54+
print file ":" line ":added:" code
55+
line++
5756
} else {
58-
# Added (+) or context ( ) line: valid on RIGHT side
59-
if (file != "" && line > 0) {
60-
print file ":" line
61-
}
57+
# Context line
58+
code = substr($0, 2) # strip leading space
59+
gsub(/\t/, " ", code)
60+
print file ":" line ":context:" code
6261
line++
6362
}
6463
}
65-
' /tmp/pr_diff.txt > /tmp/valid_anchors.txt
66-
echo "Valid anchors: $(wc -l < /tmp/valid_anchors.txt)"
64+
' /tmp/pr_diff.txt > /tmp/valid_anchors_full.txt
65+
66+
# Also create a plain file:line list for validation
67+
awk -F: '{print $1 ":" $2}' /tmp/valid_anchors_full.txt > /tmp/valid_anchors.txt
68+
69+
ADDED_COUNT=$(grep -c ':added:' /tmp/valid_anchors_full.txt || echo 0)
70+
CONTEXT_COUNT=$(grep -c ':context:' /tmp/valid_anchors_full.txt || echo 0)
71+
echo "Valid anchors: ${ADDED_COUNT} added, ${CONTEXT_COUNT} context"
6772

6873
# Step 3: Select perspectives based on changed paths
6974
PERSPECTIVES="reliability-engineer,test-engineer"
@@ -103,8 +108,27 @@ done
103108

104109
DIFF_CONTENT=$(cat /tmp/pr_diff.txt)
105110

106-
# Build the anchor list for the prompt (file:line pairs the LLM can reference)
107-
ANCHOR_LIST=$(cat /tmp/valid_anchors.txt)
111+
# Build a structured anchor table for the prompt.
112+
# Show added lines prominently, include some context lines for reference.
113+
ANCHOR_TABLE=$(awk -F: '
114+
{
115+
file = $1; line = $2; type = $3
116+
# Rejoin remaining fields as code (code may contain colons)
117+
code = ""
118+
for (i = 4; i <= NF; i++) {
119+
if (i > 4) code = code ":"
120+
code = code $i
121+
}
122+
if (type == "added") {
123+
printf " + %s:%s %s\n", file, line, code
124+
}
125+
}
126+
' /tmp/valid_anchors_full.txt)
127+
128+
# Also list context lines but more compactly (just file:line ranges)
129+
CONTEXT_SUMMARY=$(awk -F: '
130+
$3 == "context" { print $1 ":" $2 }
131+
' /tmp/valid_anchors_full.txt | head -50)
108132

109133
# Step 5: Review with each perspective, posting one PR review per perspective
110134
TOTAL_FINDINGS=0
@@ -145,20 +169,32 @@ ${KNOWLEDGE_CTX}
145169
PR Diff:
146170
${DIFF_CONTENT}
147171
148-
IMPORTANT: You must anchor findings to exact lines from this list of valid diff lines.
149-
Each entry is file:line. Only use lines from this list:
172+
=== ANCHORING INSTRUCTIONS ===
173+
174+
Each finding MUST be anchored to a specific line in the diff.
175+
Below are the ADDED lines (marked with +) that you can reference.
176+
Pick the most relevant added line for each finding.
177+
178+
ADDED LINES (preferred — use these):
179+
${ANCHOR_TABLE}
180+
181+
CONTEXT LINES (also valid, but prefer added lines above):
182+
${CONTEXT_SUMMARY}
183+
184+
For each finding, set "file" and "line" to an EXACT file:line pair from the lists above.
185+
Do NOT invent line numbers. Do NOT use line numbers that aren't listed.
150186
151-
${ANCHOR_LIST}
187+
=== OUTPUT FORMAT ===
152188
153-
Respond with a JSON array of findings. Each finding must have:
154-
- "severity": one of "critical", "important", "suggestion"
155-
- "title": a single sentence suitable as a heading
156-
- "file": exact file path from the valid lines list above
157-
- "line": exact line number from the valid lines list above, or null if no suitable anchor
158-
- "body": 2-4 sentences explaining the issue in markdown
189+
Respond with a JSON array. Each finding:
190+
- "severity": "critical" | "important" | "suggestion"
191+
- "title": one-sentence heading
192+
- "file": exact file path from the anchor lists
193+
- "line": exact line number from the anchor lists
194+
- "body": 2-4 sentence explanation in markdown
159195
160-
If you find no issues, return an empty array: []
161-
Return ONLY valid JSON — no markdown fences, no extra text.
196+
If no issues found, return: []
197+
Return ONLY valid JSON — no markdown fences, no commentary.
162198
PROMPT
163199

164200
PROMPT_CONTENT=$(cat /tmp/review_prompt.txt)

0 commit comments

Comments
 (0)