job51-gitlab-cr-node-jt-1 2.9.0 → 2.9.2
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/index.js +108 -16
- package/log +4630 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -119,14 +119,27 @@ class GitLabCodeReviewer {
|
|
|
119
119
|
const filePath = diffObject.new_path || diffObject.old_path || '';
|
|
120
120
|
this.metrics.recordBlockReviewed(reviewTime, problemsCount, hasSeriousProblems, diffSize, filePath);
|
|
121
121
|
|
|
122
|
+
// 初始化幻觉标记
|
|
123
|
+
let hallucinationDetected = false;
|
|
124
|
+
|
|
122
125
|
// 检查审查结果中是否包含严重问题,只有包含严重问题才发布评论
|
|
123
126
|
if (blockObj.review_result && blockObj.review_result.reportContent && blockObj.review_result.reportContent.includes('严重问题')) {
|
|
124
127
|
// 立即发布评论
|
|
125
|
-
await this.postSingleCommentToGitLab(projectId, mergeRequestIid, {
|
|
128
|
+
const commentResult = await this.postSingleCommentToGitLab(projectId, mergeRequestIid, {
|
|
126
129
|
diff_info: blockObj,
|
|
127
130
|
block_index: blockObj.block_index,
|
|
128
131
|
review_result: blockObj.review_result,
|
|
129
132
|
});
|
|
133
|
+
// 如果发布过程中检测到幻觉,记录标记和过滤后的报告
|
|
134
|
+
if (commentResult) {
|
|
135
|
+
if (commentResult.hallucination_detected) {
|
|
136
|
+
hallucinationDetected = true;
|
|
137
|
+
}
|
|
138
|
+
// 如果有过滤后的报告内容,使用它替代原始报告内容
|
|
139
|
+
if (commentResult.filtered_report_content) {
|
|
140
|
+
blockObj.review_result.reportContent = commentResult.filtered_report_content;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
130
143
|
} else {
|
|
131
144
|
debugLog(`该块不包含严重问题,跳过评论发布: ${blockObj.new_path || blockObj.old_path}#${blockObj.block_index}`);
|
|
132
145
|
}
|
|
@@ -136,6 +149,7 @@ class GitLabCodeReviewer {
|
|
|
136
149
|
block_index: blockObj.block_index,
|
|
137
150
|
review_result: blockObj.review_result,
|
|
138
151
|
temp_file_path: tmpFileName,
|
|
152
|
+
hallucination_detected: hallucinationDetected,
|
|
139
153
|
};
|
|
140
154
|
} catch (error) {
|
|
141
155
|
throw error;
|
|
@@ -201,9 +215,13 @@ class GitLabCodeReviewer {
|
|
|
201
215
|
collectAllReviewReports(results) {
|
|
202
216
|
let allReportsText = '';
|
|
203
217
|
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
218
|
+
// 遍历所有审查结果,过滤掉检测到幻觉的结果
|
|
219
|
+
const validResults = results.filter(result => !result.hallucination_detected);
|
|
220
|
+
|
|
221
|
+
debugLog(`汇总报告过滤:总共 ${results.length} 个结果,过滤掉 ${results.length - validResults.length} 个幻觉检测结果,保留 ${validResults.length} 个有效结果`);
|
|
222
|
+
|
|
223
|
+
for (let i = 0; i < validResults.length; i++) {
|
|
224
|
+
const result = validResults[i];
|
|
207
225
|
const filePath = result.diff_info.new_path || result.diff_info.old_path;
|
|
208
226
|
const blockIndex = result.block_index;
|
|
209
227
|
const reportContent = result.review_result?.reportContent || '';
|
|
@@ -759,6 +777,50 @@ ${allReportsText}
|
|
|
759
777
|
return fullReport;
|
|
760
778
|
}
|
|
761
779
|
|
|
780
|
+
/**
|
|
781
|
+
* 根据实际发布的问题索引生成过滤后的报告内容
|
|
782
|
+
* @param {string} fullReport 完整的 REPORT 内容
|
|
783
|
+
* @param {Array<number>} publishedProblemIndexes 正常发布的问题索引数组(从 1 开始)
|
|
784
|
+
* @returns {string} 过滤后的报告内容,只包含正常发布的问题
|
|
785
|
+
*/
|
|
786
|
+
generateFilteredReport(fullReport, publishedProblemIndexes) {
|
|
787
|
+
// 提取报告的标题部分(如 "## 🤖 AI 代码审查结果" 和 "### 🔴 严重问题")
|
|
788
|
+
const lines = fullReport.split('\n');
|
|
789
|
+
const headerLines = [];
|
|
790
|
+
let foundFirstProblem = false;
|
|
791
|
+
|
|
792
|
+
for (const line of lines) {
|
|
793
|
+
// 提取标题行(如 "## 🤖 AI 代码审查结果"、"### 🔴 严重问题" 等)
|
|
794
|
+
if (line.startsWith('##') || line.startsWith('###')) {
|
|
795
|
+
if (!line.includes('问题')) {
|
|
796
|
+
headerLines.push(line);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
// 遇到第一个问题块时停止提取标题
|
|
800
|
+
if (line.match(/\*\*问题\s*\d+\*\*/)) {
|
|
801
|
+
foundFirstProblem = true;
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// 提取每个正常发布的问题内容
|
|
807
|
+
const filteredProblemBlocks = [];
|
|
808
|
+
for (const problemIndex of publishedProblemIndexes) {
|
|
809
|
+
const problemContent = this.extractSingleProblemReport(fullReport, problemIndex);
|
|
810
|
+
if (problemContent) {
|
|
811
|
+
filteredProblemBlocks.push(problemContent);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// 组合过滤后的报告:标题 + 问题内容
|
|
816
|
+
let filteredReport = headerLines.join('\n');
|
|
817
|
+
if (filteredProblemBlocks.length > 0) {
|
|
818
|
+
filteredReport += '\n\n' + filteredProblemBlocks.join('\n\n');
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
return filteredReport;
|
|
822
|
+
}
|
|
823
|
+
|
|
762
824
|
/**
|
|
763
825
|
* 获取合并请求的最新版本信息
|
|
764
826
|
* @param {number} projectId GitLab项目ID
|
|
@@ -845,12 +907,19 @@ ${allReportsText}
|
|
|
845
907
|
if (allLineInfo.length === 0) {
|
|
846
908
|
await this.createGeneralDiscussion(projectId, mergeRequestIid, file_path_with_line, fullReportContent);
|
|
847
909
|
debugLog(`评论已发布到文件 ${file_path_with_line} (无法解析行号)`);
|
|
848
|
-
return;
|
|
910
|
+
return { hallucination_detected: false };
|
|
849
911
|
}
|
|
912
|
+
|
|
913
|
+
// 统计幻觉问题数量和正常发布数量
|
|
914
|
+
let hallucinationCount = 0;
|
|
915
|
+
let publishedCount = 0;
|
|
916
|
+
const publishedProblemIndexes = []; // 记录正常发布的问题索引(从1开始)
|
|
917
|
+
|
|
850
918
|
for (let i = 0; i < allLineInfo.length; i++) {
|
|
851
919
|
const problemInfo = allLineInfo[i];
|
|
852
920
|
debugLog(`处理第 ${i + 1}/${allLineInfo.length} 个问题:文件=${problemInfo.new_path}, 行号=${problemInfo.new_line}`);
|
|
853
|
-
const
|
|
921
|
+
const problemIndex = i + 1; // 问题索引从1开始
|
|
922
|
+
const singleProblemContent = this.extractSingleProblemReport(fullReportContent, problemIndex);
|
|
854
923
|
|
|
855
924
|
// 构建目标行号,并验证行号是否在 diff 块范围内
|
|
856
925
|
let targetLine = null;
|
|
@@ -859,7 +928,8 @@ ${allReportsText}
|
|
|
859
928
|
// 验证文件路径是否匹配当前 diff 块(检测AI幻觉)
|
|
860
929
|
if (problemInfo.new_path && diff_info.new_path &&
|
|
861
930
|
problemInfo.new_path !== diff_info.new_path) {
|
|
862
|
-
console.warn(`⚠️ 检测到AI幻觉:第 ${
|
|
931
|
+
console.warn(`⚠️ 检测到AI幻觉:第 ${problemIndex} 个问题的文件路径 ${problemInfo.new_path} 与当前 diff 块文件 ${diff_info.new_path} 不匹配,跳过该问题的评论发布`);
|
|
932
|
+
hallucinationCount++;
|
|
863
933
|
continue; // 直接跳过,不发布评论
|
|
864
934
|
}
|
|
865
935
|
|
|
@@ -903,11 +973,9 @@ ${allReportsText}
|
|
|
903
973
|
}
|
|
904
974
|
|
|
905
975
|
if (!targetLine) {
|
|
906
|
-
//
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
debugLog(`第 ${i + 1} 个问题的评论已发布 (作为一般讨论)`);
|
|
910
|
-
this.metrics.recordCommentPublished();
|
|
976
|
+
// 无法解析行号或行号超出范围,标记为幻觉问题,跳过发布
|
|
977
|
+
console.warn(`⚠️ 检测到AI幻觉:第 ${problemIndex} 个问题 ${skipReason || '无法解析行号'},该问题可能报告在上下文行或删除行,跳过发布`);
|
|
978
|
+
hallucinationCount++;
|
|
911
979
|
continue;
|
|
912
980
|
}
|
|
913
981
|
|
|
@@ -924,17 +992,41 @@ ${allReportsText}
|
|
|
924
992
|
};
|
|
925
993
|
try {
|
|
926
994
|
await this.createDiffDiscussion(projectId, mergeRequestIid, payload);
|
|
927
|
-
debugLog(`第 ${
|
|
995
|
+
debugLog(`第 ${problemIndex} 个问题的评论已发布到 ${problemInfo.new_path}#${problemInfo.new_line}`);
|
|
928
996
|
this.metrics.recordCommentPublished();
|
|
997
|
+
publishedCount++;
|
|
998
|
+
publishedProblemIndexes.push(problemIndex); // 记录正常发布的问题索引
|
|
929
999
|
} catch (error) {
|
|
930
1000
|
debugLog(`GitLab API 错误详情:${JSON.stringify(error.response?.data || error.message)}`);
|
|
931
|
-
console.error(`发布第 ${
|
|
1001
|
+
console.error(`发布第 ${problemIndex} 个问题的评论到 ${problemInfo.new_path}#${problemInfo.new_line} 失败,改用一般讨论:`, error.message);
|
|
932
1002
|
await this.createGeneralDiscussion(projectId, mergeRequestIid, file_path_with_line, singleProblemContent);
|
|
933
|
-
debugLog(`第 ${
|
|
1003
|
+
debugLog(`第 ${problemIndex} 个问题的评论已发布 (作为一般讨论)`);
|
|
934
1004
|
this.metrics.recordCommentPublished();
|
|
1005
|
+
publishedCount++;
|
|
1006
|
+
publishedProblemIndexes.push(problemIndex); // 记录正常发布的问题索引
|
|
935
1007
|
}
|
|
936
1008
|
}
|
|
937
|
-
debugLog(`所有 ${allLineInfo.length}
|
|
1009
|
+
debugLog(`所有 ${allLineInfo.length} 个问题的评论已发布完成,其中幻觉问题 ${hallucinationCount} 个,正常发布 ${publishedCount} 个`);
|
|
1010
|
+
|
|
1011
|
+
// 只有所有问题都被检测为幻觉时,才标记整个结果为幻觉
|
|
1012
|
+
const isAllHallucination = hallucinationCount > 0 && hallucinationCount === allLineInfo.length;
|
|
1013
|
+
if (isAllHallucination) {
|
|
1014
|
+
console.warn(`⚠️ 该 diff 块的所有 ${allLineInfo.length} 个问题都被检测为AI幻觉,将过滤该结果`);
|
|
1015
|
+
return { hallucination_detected: true, filtered_report_content: '' };
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// 如果部分问题正常发布,生成过滤后的报告内容(只包含正常发布的问题)
|
|
1019
|
+
let filteredReportContent = fullReportContent;
|
|
1020
|
+
if (publishedCount > 0 && publishedCount < allLineInfo.length) {
|
|
1021
|
+
console.warn(`⚠️ 该 diff 块有 ${hallucinationCount} 个问题被检测为AI幻觉,汇总报告中只保留 ${publishedCount} 个正常发布的问题`);
|
|
1022
|
+
filteredReportContent = this.generateFilteredReport(fullReportContent, publishedProblemIndexes);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// 返回幻觉标记和过滤后的报告内容
|
|
1026
|
+
return {
|
|
1027
|
+
hallucination_detected: false,
|
|
1028
|
+
filtered_report_content: filteredReportContent
|
|
1029
|
+
};
|
|
938
1030
|
} catch (error) {
|
|
939
1031
|
console.error('发布单个评论到 GitLab 失败:', error.message);
|
|
940
1032
|
throw error;
|