Compare commits
No commits in common. "c43b0f4c0999deafd457befced5272aaa72e409e" and "0735834931cfc1232eefb3d2473a2d35b4364d34" have entirely different histories.
c43b0f4c09
...
0735834931
|
|
@ -333,13 +333,16 @@ Please analyze the following code:
|
||||||
# 尝试从响应中提取JSON
|
# 尝试从响应中提取JSON
|
||||||
result = self._parse_json(content)
|
result = self._parse_json(content)
|
||||||
|
|
||||||
# 验证和清理结果
|
|
||||||
result = self._validate_analysis_result(result)
|
|
||||||
|
|
||||||
# 记录解析后的问题数量
|
# 记录解析后的问题数量
|
||||||
issues_count = len(result.get("issues", []))
|
issues_count = len(result.get("issues", []))
|
||||||
logger.info(f"📊 LLM 分析结果: 发现 {issues_count} 个问题, 质量评分: {result.get('quality_score', 'N/A')}")
|
logger.info(f"📊 LLM 分析结果: 发现 {issues_count} 个问题, 质量评分: {result.get('quality_score', 'N/A')}")
|
||||||
|
|
||||||
|
# 检查解析结果是否有效(不是默认响应)
|
||||||
|
if result == self._get_default_response():
|
||||||
|
error_msg = f"无法解析LLM响应为有效的分析结果 - Provider: {self.config.provider.value}"
|
||||||
|
logger.error(error_msg)
|
||||||
|
raise Exception(error_msg)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -760,54 +763,6 @@ Please analyze the following code:
|
||||||
|
|
||||||
raise ValueError(f"json-repair returned unexpected type: {type(repaired)}")
|
raise ValueError(f"json-repair returned unexpected type: {type(repaired)}")
|
||||||
|
|
||||||
def _validate_analysis_result(self, result: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""验证和清理分析结果"""
|
|
||||||
if not isinstance(result, dict):
|
|
||||||
logger.warning(f"分析结果不是字典类型: {type(result)}")
|
|
||||||
return self._get_default_response()
|
|
||||||
|
|
||||||
# 确保 issues 是列表,且每个元素都是字典
|
|
||||||
raw_issues = result.get("issues", [])
|
|
||||||
if not isinstance(raw_issues, list):
|
|
||||||
logger.warning(f"issues 字段不是列表类型: {type(raw_issues)}")
|
|
||||||
raw_issues = []
|
|
||||||
|
|
||||||
valid_issues = []
|
|
||||||
for i, issue in enumerate(raw_issues):
|
|
||||||
if isinstance(issue, dict):
|
|
||||||
valid_issues.append(issue)
|
|
||||||
else:
|
|
||||||
logger.warning(f"忽略无效的问题格式 (index {i}): {type(issue)}")
|
|
||||||
|
|
||||||
result["issues"] = valid_issues
|
|
||||||
|
|
||||||
# 确保 quality_score 是数字
|
|
||||||
score = result.get("quality_score")
|
|
||||||
if score is None or not isinstance(score, (int, float)):
|
|
||||||
try:
|
|
||||||
if score is not None:
|
|
||||||
result["quality_score"] = int(float(str(score)))
|
|
||||||
else:
|
|
||||||
result["quality_score"] = 80
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
result["quality_score"] = 80
|
|
||||||
|
|
||||||
# 确保 summary 和 metrics 存在
|
|
||||||
if "summary" not in result or not isinstance(result["summary"], dict):
|
|
||||||
num_issues = len(valid_issues)
|
|
||||||
result["summary"] = {
|
|
||||||
"total_issues": num_issues,
|
|
||||||
"critical_issues": sum(1 for iss in valid_issues if iss.get("severity") == "critical"),
|
|
||||||
"high_issues": sum(1 for iss in valid_issues if iss.get("severity") == "high"),
|
|
||||||
"medium_issues": sum(1 for iss in valid_issues if iss.get("severity") == "medium"),
|
|
||||||
"low_issues": sum(1 for iss in valid_issues if iss.get("severity") == "low")
|
|
||||||
}
|
|
||||||
|
|
||||||
if "metrics" not in result or not isinstance(result["metrics"], dict):
|
|
||||||
result["metrics"] = self._get_default_response()["metrics"]
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _get_default_response(self) -> Dict[str, Any]:
|
def _get_default_response(self) -> Dict[str, Any]:
|
||||||
"""返回默认响应"""
|
"""返回默认响应"""
|
||||||
return {
|
return {
|
||||||
|
|
@ -960,8 +915,6 @@ Please analyze the following code:
|
||||||
raise Exception("LLM返回空响应")
|
raise Exception("LLM返回空响应")
|
||||||
|
|
||||||
result = self._parse_json(content)
|
result = self._parse_json(content)
|
||||||
# 验证和清理结果
|
|
||||||
result = self._validate_analysis_result(result)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -680,24 +680,8 @@ async def scan_repo_task(task_id: str, db_session_factory, user_config: dict = N
|
||||||
# 保存问题
|
# 保存问题
|
||||||
issues = analysis.get("issues", [])
|
issues = analysis.get("issues", [])
|
||||||
for issue in issues:
|
for issue in issues:
|
||||||
try:
|
|
||||||
# 防御性检查:确保 issue 是字典
|
|
||||||
if not isinstance(issue, dict):
|
|
||||||
print(f"⚠️ 警告: 任务 {task_id} 中文件 {f_path} 的分析结果包含无效的问题格式: {issue}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
# 辅助函数:清理字符串中 PostgreSQL 不支持的字符
|
|
||||||
def sanitize_for_db(text):
|
|
||||||
if text is None:
|
|
||||||
return None
|
|
||||||
if not isinstance(text, str):
|
|
||||||
text = str(text)
|
|
||||||
# 移除 NULL 字节 (PostgreSQL 不支持)
|
|
||||||
text = text.replace('\x00', '')
|
|
||||||
return text
|
|
||||||
|
|
||||||
line_num = issue.get("line", 1)
|
line_num = issue.get("line", 1)
|
||||||
code_snippet = sanitize_for_db(issue.get("code_snippet"))
|
code_snippet = issue.get("code_snippet")
|
||||||
if not code_snippet or len(code_snippet.strip()) < 5:
|
if not code_snippet or len(code_snippet.strip()) < 5:
|
||||||
try:
|
try:
|
||||||
idx = max(0, int(line_num) - 1)
|
idx = max(0, int(line_num) - 1)
|
||||||
|
|
@ -714,25 +698,18 @@ async def scan_repo_task(task_id: str, db_session_factory, user_config: dict = N
|
||||||
column_number=issue.get("column"),
|
column_number=issue.get("column"),
|
||||||
issue_type=issue.get("type", "maintainability"),
|
issue_type=issue.get("type", "maintainability"),
|
||||||
severity=issue.get("severity", "low"),
|
severity=issue.get("severity", "low"),
|
||||||
title=sanitize_for_db(issue.get("title", "Issue")),
|
title=issue.get("title", "Issue"),
|
||||||
message=sanitize_for_db(issue.get("description") or issue.get("title", "Issue")),
|
message=issue.get("description") or issue.get("title", "Issue"),
|
||||||
suggestion=sanitize_for_db(issue.get("suggestion")),
|
suggestion=issue.get("suggestion"),
|
||||||
code_snippet=code_snippet,
|
code_snippet=code_snippet,
|
||||||
ai_explanation=sanitize_for_db(issue.get("ai_explanation")),
|
ai_explanation=issue.get("ai_explanation"),
|
||||||
status="open"
|
status="open"
|
||||||
)
|
)
|
||||||
db.add(audit_issue)
|
db.add(audit_issue)
|
||||||
total_issues += 1
|
total_issues += 1
|
||||||
except Exception as e:
|
|
||||||
print(f"⚠️ 处理单个问题时出错 (文件 {f_path}): {e}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if "quality_score" in analysis:
|
if "quality_score" in analysis:
|
||||||
try:
|
quality_scores.append(analysis["quality_score"])
|
||||||
quality_score = float(analysis["quality_score"])
|
|
||||||
quality_scores.append(quality_score)
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# 更新主任务进度
|
# 更新主任务进度
|
||||||
processed_count = scanned_files + failed_files
|
processed_count = scanned_files + failed_files
|
||||||
|
|
|
||||||
|
|
@ -878,7 +878,7 @@ export default function ProjectDetail() {
|
||||||
|
|
||||||
{/* 审计选项对话框 */}
|
{/* 审计选项对话框 */}
|
||||||
<Dialog open={showAuditOptionsDialog} onOpenChange={setShowAuditOptionsDialog}>
|
<Dialog open={showAuditOptionsDialog} onOpenChange={setShowAuditOptionsDialog}>
|
||||||
<DialogContent className="max-w-md cyber-card border-border cyber-dialog p-0 !fixed">
|
<DialogContent className="max-w-md cyber-card border-border cyber-dialog p-0">
|
||||||
{/* Terminal Header */}
|
{/* Terminal Header */}
|
||||||
<div className="flex items-center gap-2 px-4 py-3 cyber-bg-elevated border-b border-border">
|
<div className="flex items-center gap-2 px-4 py-3 cyber-bg-elevated border-b border-border">
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue