fix(ai-review comment): 顯示審查問題原因

This commit is contained in:
2026-06-22 10:27:33 +00:00
parent bbd7570a5b
commit f83a2034a8
7 changed files with 23 additions and 6 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ function inlineCommentBody(f) {
}
function problemText(f) {
return f.problem || f.title || f.message || f.location || '未提供問題位置';
return f.problem || f.reason || f.description || f.detail || f.title || f.message || '未提供問題原因';
}
function reviewCommentBody(f) {
+14 -1
View File
@@ -212,7 +212,8 @@ describe('postFindingsReview', () => {
);
assert.match(reviewCalls[0].comments[0].body, /嚴重等級/);
assert.match(reviewCalls[0].comments[0].body, /.*Rex/s);
assert.match(reviewCalls[0].comments[0].body, /.*app\/a\.js:10/s);
assert.match(reviewCalls[0].comments[0].body, /.*/s);
assert.doesNotMatch(reviewCalls[0].comments[0].body, /.*app\/a\.js:10/s);
assert.match(reviewCalls[0].comments[0].body, /.*C/s);
});
@@ -242,4 +243,16 @@ describe('postFindingsReview', () => {
assert.match(reviewCalls[0].comments[0].body, /.*/s);
assert.match(reviewCalls[0].comments[0].body, /.*/s);
});
it('uses reviewer reason fields as the problem text instead of the location', async () => {
const reviewCalls = [];
await postFindingsReview([
{ level: 'warning', role: 'Leo', location: 'app/a.js:5', description: '這裡缺少空值檢查', suggestion: '先判斷 null 再使用' },
], {
postReview: async (args) => { reviewCalls.push(args); },
});
assert.match(reviewCalls[0].comments[0].body, /.*/s);
assert.doesNotMatch(reviewCalls[0].comments[0].body, /.*app\/a\.js:5/s);
});
});
+1 -1
View File
@@ -246,7 +246,7 @@ function fallback(label, findings, e) {
/** 只保留 AI 需要的欄位,減少 token 用量 */
function toAIPayload(findings) {
return findings.map(({ level, role, location, suggestion }) => ({ level, role, location, suggestion }));
return findings.map(({ level, role, location, problem, suggestion }) => ({ level, role, location, problem, suggestion }));
}
/**
+2 -1
View File
@@ -115,7 +115,7 @@ describe('findings exclusions', () => {
it('builds a compact exclusion hint for AI', async () => {
const findings = [
{ level: 'warning', role: 'Maya', location: 'src/app.cs:12', suggestion: 'update tests' },
{ level: 'warning', role: 'Maya', location: 'src/app.cs:12', problem: '缺少測試驗證', suggestion: 'update tests' },
];
const exclusions = [
{ location: 'src/app.cs:1', original_finding: '更新套件後請補上測試驗證' },
@@ -138,6 +138,7 @@ describe('findings exclusions', () => {
assert.ok(capturedSystemPrompt.includes('paths=src/app.cs, src/service.cs'));
assert.ok(capturedSystemPrompt.includes('請確認安全性變更'));
assert.ok(capturedUserContent.includes('"location":"src/app.cs:12"'));
assert.ok(capturedUserContent.includes('"problem":"缺少測試驗證"'));
assert.ok(capturedUserContent.includes('"suggestion":"update tests"'));
});
+1
View File
@@ -71,6 +71,7 @@ export function buildAnalysisPrompt(role) {
' "level": "critical|warning|info",',
` "role": "${role.name}",`,
' "location": "檔案路徑:行號 或 檔案路徑",',
' "problem": "繁體中文(台灣用語)說明審查員認為這裡有問題的原因,不要只填檔案路徑或行號",',
' "suggestion": "繁體中文(台灣用語)的具體修改建議"',
'}',
'',
+2
View File
@@ -68,6 +68,8 @@ describe('buildAnalysisPrompt', () => {
it('embeds the role name in the JSON contract and persona/body', () => {
const prompt = buildAnalysisPrompt(parseRoleFile(SAMPLE));
assert.match(prompt, /"role": "Tester"/);
assert.match(prompt, /"problem":/);
assert.match(prompt, /有問題的原因/);
assert.match(prompt, /冷靜嚴謹/);
assert.match(prompt, /審查重點:邊界與空值/);
assert.match(prompt, /只回傳 JSON 陣列/);