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