@krotovm/gitlab-ai-review 1.0.28 → 1.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cli/ci-review.js +17 -6
- package/dist/prompt/index.js +1 -1
- package/dist/prompt/templates/triage-system.js +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ stages: [review]
|
|
|
23
23
|
|
|
24
24
|
ai_review:
|
|
25
25
|
stage: review
|
|
26
|
-
image: node:
|
|
26
|
+
image: node:24
|
|
27
27
|
rules:
|
|
28
28
|
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
29
29
|
script:
|
|
@@ -37,7 +37,7 @@ stages: [review]
|
|
|
37
37
|
|
|
38
38
|
ai_review:
|
|
39
39
|
stage: review
|
|
40
|
-
image: node:
|
|
40
|
+
image: node:24
|
|
41
41
|
rules:
|
|
42
42
|
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
43
43
|
script:
|
package/dist/cli/ci-review.js
CHANGED
|
@@ -598,6 +598,7 @@ export async function reviewMergeRequestMultiPass(params) {
|
|
|
598
598
|
}));
|
|
599
599
|
const triageMessages = buildTriagePrompt(triageInputs);
|
|
600
600
|
let triageResult = null;
|
|
601
|
+
let triageText = null;
|
|
601
602
|
try {
|
|
602
603
|
const triageCompletion = await createCompletionWithDebug({
|
|
603
604
|
openaiInstance,
|
|
@@ -612,7 +613,7 @@ export async function reviewMergeRequestMultiPass(params) {
|
|
|
612
613
|
response_format: { type: "json_object" },
|
|
613
614
|
},
|
|
614
615
|
});
|
|
615
|
-
|
|
616
|
+
triageText = extractCompletionText(triageCompletion);
|
|
616
617
|
if (triageText != null)
|
|
617
618
|
triageResult = parseTriageResponse(triageText);
|
|
618
619
|
}
|
|
@@ -620,7 +621,15 @@ export async function reviewMergeRequestMultiPass(params) {
|
|
|
620
621
|
logStep(`Triage pass failed: ${error?.message ?? error}. Falling back to single-pass.`);
|
|
621
622
|
}
|
|
622
623
|
if (triageResult == null) {
|
|
623
|
-
|
|
624
|
+
if (triageText != null) {
|
|
625
|
+
const triagePreview = triageText.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
626
|
+
const looksLikeHtml = /<html|<!doctype html/i.test(triageText);
|
|
627
|
+
logStep(`Triage parse failed: expected JSON but got ${looksLikeHtml ? "HTML/non-JSON" : "non-JSON"} response. Preview: ${triagePreview || "<empty>"}`);
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
logStep("Triage parse failed: model returned empty response body.");
|
|
631
|
+
}
|
|
632
|
+
logStep("Falling back to single-pass pipeline.");
|
|
624
633
|
return await reviewMergeRequestWithTools({
|
|
625
634
|
openaiInstance,
|
|
626
635
|
aiModel,
|
|
@@ -637,12 +646,14 @@ export async function reviewMergeRequestMultiPass(params) {
|
|
|
637
646
|
});
|
|
638
647
|
}
|
|
639
648
|
const triageMap = new Map(triageResult.files.map((f) => [f.path, f.verdict]));
|
|
640
|
-
|
|
649
|
+
let reviewFiles = changes.filter((c) => triageMap.get(c.new_path) !== "SKIP");
|
|
641
650
|
const skippedCount = changes.length - reviewFiles.length;
|
|
642
|
-
logStep(`Triage: ${reviewFiles.length} file(s) to review, ${skippedCount} skipped. Summary: ${triageResult.summary.slice(0, 120)}...`);
|
|
643
651
|
if (reviewFiles.length === 0) {
|
|
644
|
-
|
|
645
|
-
|
|
652
|
+
logStep(`Triage wanted to skip all ${changes.length} file(s) — overriding to review all. Summary: ${triageResult.summary.slice(0, 120)}...`);
|
|
653
|
+
reviewFiles = changes;
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
logStep(`Triage: ${reviewFiles.length} file(s) to review, ${skippedCount} skipped. Summary: ${triageResult.summary.slice(0, 120)}...`);
|
|
646
657
|
}
|
|
647
658
|
logStep(`Pass 2/4: reviewing ${reviewFiles.length} file(s) (concurrency=${reviewConcurrency})`);
|
|
648
659
|
const allChangedPaths = changes.map((c) => c.new_path);
|
package/dist/prompt/index.js
CHANGED
|
@@ -126,7 +126,7 @@ export function buildConsolidatePrompt(params) {
|
|
|
126
126
|
];
|
|
127
127
|
}
|
|
128
128
|
export function buildVerificationPrompt(params) {
|
|
129
|
-
const { perFileFindings, summary, consolidatedFindings, maxFindings, refs
|
|
129
|
+
const { perFileFindings, summary, consolidatedFindings, maxFindings, refs } = params;
|
|
130
130
|
const findingsText = perFileFindings
|
|
131
131
|
.map((f) => `### ${f.path}\n${f.findings}`)
|
|
132
132
|
.join("\n\n");
|
|
@@ -10,8 +10,12 @@ export const TRIAGE_SYSTEM_LINES = [
|
|
|
10
10
|
"",
|
|
11
11
|
"Rules:",
|
|
12
12
|
"- When in doubt, verdict is NEEDS_REVIEW.",
|
|
13
|
+
"- Look beyond comments and JSDoc: if the diff changes function signatures, return types, control flow, variable assignments, or adds/removes code lines (not just comments), it is a logic change → NEEDS_REVIEW.",
|
|
14
|
+
"- If a file mixes doc/comment edits with actual code changes, verdict is NEEDS_REVIEW.",
|
|
15
|
+
"- Refactoring (splitting/merging functions, changing data structures, renaming with signature changes) is NEEDS_REVIEW.",
|
|
13
16
|
"- Deleted files are SKIP unless the deletion could break dependents.",
|
|
14
17
|
"- New files containing logic are NEEDS_REVIEW.",
|
|
15
|
-
"- Test
|
|
18
|
+
"- Test files that add, remove, or change assertions or expected values are NEEDS_REVIEW.",
|
|
19
|
+
"- Test-only files are SKIP only if changes are purely cosmetic (formatting, comments).",
|
|
16
20
|
"- Config/CI/docs files are SKIP unless they modify build targets, env vars, or secrets.",
|
|
17
21
|
];
|