feat(ai-review 對話收斂與誤報裁決): 對話一律關閉並三分類,誤報改由防守方角色平行 sub-agent 裁決
This commit is contained in:
+11
-8
@@ -2,7 +2,7 @@ import path from 'path';
|
||||
import { GITEA_REPOSITORY, PR_NUMBER, PR_HEAD_BRANCH, PR_BASE_BRANCH, getLLMConfig, FINDINGS_PATH, EXCLUSIONS_PATH } from './config.js';
|
||||
import { loadRoles, getRoleIntro } from './roles.js';
|
||||
import { getPRDiff, postComment, getCommitMessageBySha, getBotReviewOutcome, shouldSkipBotCommit } from './gitea.js';
|
||||
import { analyzeWithRole, loadOldFindings, mergeFindings, sortByLevel, deduplicateWithAI, loadExclusions, applyExclusions, filterFalsePositivesWithAI } from './findings.js';
|
||||
import { analyzeWithRole, loadOldFindings, mergeFindings, sortByLevel, deduplicateWithAI, loadExclusions, applyExclusions, filterFalsePositivesWithAI, appendExclusions } from './findings.js';
|
||||
import { reconcileConversations, dropResolvedFindings, addCarriedFindings } from './resolve.js';
|
||||
import { saveFindings, postFindingsReview, formatFindingsStatsLine } from './comments.js';
|
||||
import { getRunUsage, getRateLimit, fetchAccountQuota, formatUsageStats, formatUsageStatsLine } from './usage.js';
|
||||
@@ -46,12 +46,10 @@ async function main() {
|
||||
}
|
||||
|
||||
step('Step2', 'PR 對話收斂');
|
||||
let reconcile = { resolvedFindings: [], carriedFindings: [], resolvedCount: 0, duplicateCount: 0, unresolvedCount: 0 };
|
||||
let reconcile = { resolvedFindings: [], excludedFindings: [], carriedFindings: [], resolvedCount: 0, falsePositiveCount: 0, openCount: 0, closedCount: 0 };
|
||||
try {
|
||||
// 載入來源分支既有的舊問題,供對話收斂判斷「未修復但已存在於舊問題」的情況
|
||||
const oldFindingsForReconcile = loadOldFindings(WORKSPACE);
|
||||
reconcile = await reconcileConversations({ oldFindings: oldFindingsForReconcile });
|
||||
ok(`Step2 完成: resolved=${reconcile.resolvedCount} duplicate=${reconcile.duplicateCount} 加回=${reconcile.carriedFindings.length}`);
|
||||
reconcile = await reconcileConversations();
|
||||
ok(`Step2 完成: 關閉=${reconcile.closedCount} 已修復=${reconcile.resolvedCount} 誤報=${reconcile.falsePositiveCount} 加回=${reconcile.carriedFindings.length}`);
|
||||
} catch (e) {
|
||||
warn(`Step2 對話收斂失敗(繼續執行): ${e.message}`);
|
||||
}
|
||||
@@ -115,9 +113,10 @@ async function main() {
|
||||
let oldFindings = loadOldFindings(repoDir || WORKSPACE);
|
||||
logFindingsStats('Step4 舊 findings 統計', oldFindings);
|
||||
const beforeReconcile = oldFindings.length;
|
||||
oldFindings = dropResolvedFindings(oldFindings, reconcile.resolvedFindings);
|
||||
const reconcileDropped = [...reconcile.resolvedFindings, ...reconcile.excludedFindings];
|
||||
oldFindings = dropResolvedFindings(oldFindings, reconcileDropped);
|
||||
oldFindings = addCarriedFindings(oldFindings, reconcile.carriedFindings);
|
||||
line(`Step4 對話收斂套用: ${beforeReconcile} -> ${oldFindings.length} 筆(移除已解決 ${reconcile.resolvedFindings.length}、加回未解決 ${reconcile.carriedFindings.length})`);
|
||||
line(`Step4 對話收斂套用: ${beforeReconcile} -> ${oldFindings.length} 筆(移除已修復 ${reconcile.resolvedFindings.length}、移除誤報 ${reconcile.excludedFindings.length}、加回仍成立 ${reconcile.carriedFindings.length})`);
|
||||
logFindingsStats('Step4 收斂後舊 findings 統計', oldFindings);
|
||||
logFindingsStats('Step4 新 findings 統計', newFindings);
|
||||
const mergedFindings = mergeFindings(oldFindings, newFindings);
|
||||
@@ -130,6 +129,10 @@ async function main() {
|
||||
logFindingsStats('Step4 排序後統計', sorted);
|
||||
|
||||
step('Step5', 'AI 排除問題過濾');
|
||||
// 先把對話收斂判定的誤報寫入 exclusions.json(workspace 與 cloned repo 各一份),供本次過濾與後續 commit
|
||||
if (reconcile.excludedFindings.length > 0) {
|
||||
appendExclusions(WORKSPACE, reconcile.excludedFindings, repoDir || WORKSPACE);
|
||||
}
|
||||
const exclusions = loadExclusions(repoDir || WORKSPACE, repoState, WORKSPACE);
|
||||
const ruleFiltered = applyExclusions(sorted, exclusions);
|
||||
logFindingsStats('Step5 規則排除後統計', ruleFiltered);
|
||||
|
||||
Reference in New Issue
Block a user