fix(ai-review 對話收斂): 並行取檔與 resolve、處理單檔失敗與無路徑留言
This commit is contained in:
+31
-13
@@ -49,6 +49,7 @@ export function groupConversations(comments) {
|
||||
const groups = new Map();
|
||||
for (const c of comments || []) {
|
||||
const filePath = typeof c?.path === 'string' ? c.path : '';
|
||||
if (!filePath) continue; // 無檔案路徑的留言無法定位,跳過以免併入共用群組
|
||||
const lineNum = Number(c?.position) || Number(c?.original_position) || 0;
|
||||
const key = `${filePath}|${lineNum}`;
|
||||
if (!groups.has(key)) {
|
||||
@@ -129,10 +130,17 @@ export async function reconcileConversations(deps = {}) {
|
||||
line(`對話收斂: 對話總數=${conversations.length} 已解決/不可處理=${alreadyResolved} 待判斷=${open.length}`);
|
||||
if (open.length === 0) return { ...EMPTY };
|
||||
|
||||
// 並行取得各檔案最新內容;單一檔案失敗時視為空字串,不中斷整體流程
|
||||
const fileCache = new Map();
|
||||
for (const filePath of [...new Set(open.map(c => c.path).filter(Boolean))]) {
|
||||
fileCache.set(filePath, await getFileContent(filePath));
|
||||
}
|
||||
const filePaths = [...new Set(open.map(c => c.path).filter(Boolean))];
|
||||
await Promise.all(filePaths.map(async (filePath) => {
|
||||
try {
|
||||
fileCache.set(filePath, await getFileContent(filePath));
|
||||
} catch (e) {
|
||||
warn(`取得檔案內容失敗(視為空): ${filePath} error=${e.message}`);
|
||||
fileCache.set(filePath, '');
|
||||
}
|
||||
}));
|
||||
|
||||
const items = open.map((c, idx) => ({
|
||||
idx,
|
||||
@@ -153,19 +161,29 @@ export async function reconcileConversations(deps = {}) {
|
||||
|
||||
const resolvedFindings = [];
|
||||
const carriedFindings = [];
|
||||
|
||||
// 並行 resolve 所有 AI 判定已解決的對話(allSettled:個別失敗不中斷其他)
|
||||
const resolveTargets = open
|
||||
.map((c, i) => ({ c, i }))
|
||||
.filter(({ i }) => resolvedSet.has(i));
|
||||
const settled = await Promise.allSettled(
|
||||
resolveTargets.map(({ c }) => resolveComment(c.commentIds[0])),
|
||||
);
|
||||
const resolveOutcome = new Map();
|
||||
resolveTargets.forEach(({ i }, j) => resolveOutcome.set(i, settled[j]));
|
||||
|
||||
let resolvedCount = 0;
|
||||
for (let i = 0; i < open.length; i++) {
|
||||
const c = open[i];
|
||||
if (resolvedSet.has(i)) {
|
||||
try {
|
||||
await resolveComment(c.commentIds[0]);
|
||||
resolvedCount += 1;
|
||||
if (c.botFinding) resolvedFindings.push({ ...c.botFinding, is_new: false });
|
||||
ok(`對話已解決並 resolve: ${c.path}:${c.line}`);
|
||||
continue;
|
||||
} catch (e) {
|
||||
warn(`resolve 對話失敗(保留為未解決): ${c.path}:${c.line} error=${e.message}`);
|
||||
}
|
||||
const outcome = resolveOutcome.get(i);
|
||||
if (outcome?.status === 'fulfilled') {
|
||||
resolvedCount += 1;
|
||||
if (c.botFinding) resolvedFindings.push({ ...c.botFinding, is_new: false });
|
||||
ok(`對話已解決並 resolve: ${c.path}:${c.line}`);
|
||||
continue;
|
||||
}
|
||||
if (outcome?.status === 'rejected') {
|
||||
warn(`resolve 對話失敗(保留為未解決): ${c.path}:${c.line} error=${outcome.reason?.message}`);
|
||||
}
|
||||
pushCarried(carriedFindings, c);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user