fix(審查流程): 修復 AI 去重超量、clone 失敗誤持久化、留言行號漏 new_position
This commit is contained in:
+11
-6
@@ -420,13 +420,18 @@ export async function deduplicateWithAI(findings) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await chatJSON(systemPrompt, JSON.stringify(toAIPayload(findings)));
|
const result = await chatJSON(systemPrompt, JSON.stringify(toAIPayload(findings)));
|
||||||
if (Array.isArray(result) && result.length > 0) {
|
// 去重結果數量不得超過輸入(避免 LLM 無中生有),且每筆都必須能對應回原始 finding。
|
||||||
ok(`AI 去重: ${findings.length} -> ${result.length} 筆`);
|
if (Array.isArray(result) && result.length > 0 && result.length <= findings.length) {
|
||||||
// 以 location+suggestion 為 key,將原始 findings 的完整欄位(含 is_new)補回
|
const keyOf = f => `${f.location}|${String(f.suggestion).slice(0, 50)}`;
|
||||||
const origMap = new Map(findings.map(f => [`${f.location}|${String(f.suggestion).slice(0, 50)}`, f]));
|
const origMap = new Map(findings.map(f => [keyOf(f), f]));
|
||||||
return result.map(r => origMap.get(`${r.location}|${String(r.suggestion).slice(0, 50)}`) ?? r);
|
// 只保留能對應回原始 finding 的項目,丟棄無法對應(可能為幻覺)的結果
|
||||||
|
const mapped = result.map(r => origMap.get(keyOf(r))).filter(Boolean);
|
||||||
|
if (mapped.length > 0) {
|
||||||
|
ok(`AI 去重: ${findings.length} -> ${mapped.length} 筆`);
|
||||||
|
return mapped;
|
||||||
}
|
}
|
||||||
throw new Error('AI 回傳空陣列');
|
}
|
||||||
|
throw new Error('AI 去重結果異常(空、超量或無法對應原始 findings)');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return fallback('AI 去重', findings, e);
|
return fallback('AI 去重', findings, e);
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -209,7 +209,13 @@ async function main() {
|
|||||||
step('Step10', '記憶區 Commit/Push');
|
step('Step10', '記憶區 Commit/Push');
|
||||||
const reviewOutcome = filtered.some(f => f.level === 'critical') ? 'failure' : 'success';
|
const reviewOutcome = filtered.some(f => f.level === 'critical') ? 'failure' : 'success';
|
||||||
input(`review outcome=${reviewOutcome}`);
|
input(`review outcome=${reviewOutcome}`);
|
||||||
await commitAndPush(WORKSPACE, repoDir || WORKSPACE, undefined, undefined, reviewOutcome);
|
// clone 失敗(repoDir 為 undefined)時不可把 WORKSPACE(非來源分支 git repo)當 repoDir,
|
||||||
|
// 否則會在錯誤的工作目錄嘗試 commit/push,findings/exclusions 無法持久化到 PR 分支。
|
||||||
|
if (!repoDir) {
|
||||||
|
warn('來源分支 clone 失敗,略過 findings/exclusions 持久化(不以 WORKSPACE 當 repoDir)');
|
||||||
|
} else {
|
||||||
|
await commitAndPush(WORKSPACE, repoDir, undefined, undefined, reviewOutcome);
|
||||||
|
}
|
||||||
|
|
||||||
// Step11 嚴重問題把關
|
// Step11 嚴重問題把關
|
||||||
step('Step11', '嚴重問題把關');
|
step('Step11', '嚴重問題把關');
|
||||||
|
|||||||
+1
-1
@@ -75,7 +75,7 @@ export function groupConversations(comments) {
|
|||||||
for (const c of comments || []) {
|
for (const c of comments || []) {
|
||||||
const filePath = typeof c?.path === 'string' ? c.path : '';
|
const filePath = typeof c?.path === 'string' ? c.path : '';
|
||||||
if (!filePath) continue; // 無檔案路徑的留言無法定位,跳過以免併入共用群組
|
if (!filePath) continue; // 無檔案路徑的留言無法定位,跳過以免併入共用群組
|
||||||
const lineNum = Number(c?.position) || Number(c?.original_position) || 0;
|
const lineNum = Number(c?.position) || Number(c?.new_position) || Number(c?.original_position) || 0;
|
||||||
const key = `${filePath}|${lineNum}`;
|
const key = `${filePath}|${lineNum}`;
|
||||||
if (!groups.has(key)) {
|
if (!groups.has(key)) {
|
||||||
groups.set(key, { key, path: filePath, line: lineNum, commentIds: [], bodies: [], resolved: false, botFinding: null });
|
groups.set(key, { key, path: filePath, line: lineNum, commentIds: [], bodies: [], resolved: false, botFinding: null });
|
||||||
|
|||||||
Reference in New Issue
Block a user