Skip to content
3 changes: 2 additions & 1 deletion autobot-backend/agents/security_scanner_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from autobot_shared.http_client import get_http_client
from autobot_shared.logging_manager import get_logger
from autobot_shared.status_enums import Severity
from constants.network_constants import NetworkConstants
from constants.threshold_constants import TimingConstants
from utils.agent_command_helpers import run_agent_command
Expand Down Expand Up @@ -469,7 +470,7 @@ def _parse_vulnerabilities(self, output: str) -> List[Dict[str, Any]]:
vulnerabilities.append(
{
"vulnerability": lines[0].strip(),
"severity": "unknown",
"severity": Severity.UNKNOWN.value,
"description": ("\n".join(lines[1:3]) if len(lines) > 1 else ""),
}
)
Expand Down
5 changes: 3 additions & 2 deletions autobot-backend/api/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
from autobot_shared.error_boundaries import ErrorCategory, with_error_handling
from autobot_shared.logging_manager import get_logger
from autobot_shared.redis_client import RedisDatabase
from autobot_shared.status_enums import Severity
from autobot_shared.time_utils import parse_utc_iso
from constants.network_constants import NetworkConstants
from constants.threshold_constants import TimingConstants
Expand Down Expand Up @@ -205,7 +206,7 @@ def _check_resource_alerts(system_resources: Dict) -> List[Dict[str, Any]]:
{
"type": "cpu_high",
"message": f"CPU usage at {cpu_usage:.1f}%",
"severity": "warning",
"severity": Severity.WARNING.value,
}
)

Expand All @@ -216,7 +217,7 @@ def _check_resource_alerts(system_resources: Dict) -> List[Dict[str, Any]]:
{
"type": "memory_high",
"message": f"Memory usage at {memory_usage:.1f}%",
"severity": "warning",
"severity": Severity.WARNING.value,
}
)

Expand Down
9 changes: 5 additions & 4 deletions autobot-backend/api/analytics_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from auth_middleware import check_admin_permission
from autobot_shared.error_boundaries import ErrorCategory, with_error_handling
from autobot_shared.logging_manager import get_logger
from autobot_shared.status_enums import Severity
from services.agent_analytics import AgentType, TaskStatus, get_agent_analytics

logger = get_logger(__name__)
Expand Down Expand Up @@ -224,7 +225,7 @@ def _check_agent_metrics(metrics) -> list:
recommendations.append(
{
"type": "high_error_rate",
"severity": "high" if metrics.error_rate > 25 else "medium",
"severity": Severity.HIGH.value if metrics.error_rate > 25 else "medium",
"message": f"Error rate of {metrics.error_rate:.1f}% exceeds threshold",
"suggestion": "Review error logs and improve error handling",
}
Expand All @@ -234,7 +235,7 @@ def _check_agent_metrics(metrics) -> list:
recommendations.append(
{
"type": "slow_performance",
"severity": "medium",
"severity": Severity.MEDIUM.value,
"message": f"Average duration of {metrics.avg_duration_ms/1000:.1f}s is high",
"suggestion": "Consider optimizing task processing or increasing resources",
}
Expand All @@ -246,7 +247,7 @@ def _check_agent_metrics(metrics) -> list:
recommendations.append(
{
"type": "timeout_issues",
"severity": "high" if timeout_rate > 15 else "medium",
"severity": Severity.HIGH.value if timeout_rate > 15 else "medium",
"message": f"Timeout rate of {timeout_rate:.1f}% indicates issues",
"suggestion": "Increase timeout limits or optimize long-running operations",
}
Expand All @@ -263,7 +264,7 @@ def _check_agent_metrics(metrics) -> list:
recommendations.append(
{
"type": "low_activity",
"severity": "low",
"severity": Severity.LOW.value,
"message": "No activity in the last 7 days",
"suggestion": "Check if agent is properly configured and active",
}
Expand Down
6 changes: 3 additions & 3 deletions autobot-backend/api/analytics_bug_prediction.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ async def _run_bug_analysis(path: str, include_pattern: str, limit: int) -> dict
analyzed_files.sort(key=lambda x: x["risk_score"], reverse=True)
high_risk = sum(1 for f in analyzed_files if f["risk_score"] >= 60)

risk_dist = {level.value: 0 for level in RiskLevel}
risk_dist = {level.value: 0 for level in RiskLevel.score_ladder()}
for f in analyzed_files:
level = get_risk_level(f["risk_score"])
risk_dist[level.value] += 1
Expand Down Expand Up @@ -868,7 +868,7 @@ def _build_analysis_result(
"""Build the final result dict for a completed analysis (#1418)."""
analyzed_files.sort(key=lambda x: x["risk_score"], reverse=True)
high_risk = sum(1 for f in analyzed_files if f["risk_score"] >= 60)
risk_dist = {level.value: 0 for level in RiskLevel}
risk_dist = {level.value: 0 for level in RiskLevel.score_ladder()}
for f in analyzed_files:
level = get_risk_level(f["risk_score"])
risk_dist[level.value] += 1
Expand Down Expand Up @@ -1230,7 +1230,7 @@ def _calculate_risk_distribution(analyzed_files: list) -> dict[str, int]:
Returns:
Dict mapping risk level names to counts
"""
risk_dist = {level.value: 0 for level in RiskLevel}
risk_dist = {level.value: 0 for level in RiskLevel.score_ladder()}
for f in analyzed_files:
level = get_risk_level(f["risk_score"])
risk_dist[level.value] += 1
Expand Down
5 changes: 3 additions & 2 deletions autobot-backend/api/analytics_llm_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from autobot_shared.logging_manager import get_logger
from autobot_shared.redis_client import RedisDatabase
from autobot_shared.redis_mixin import AsyncRedisClientMixin
from autobot_shared.status_enums import Severity
from constants.model_constants import (
EXPENSIVE_MODEL_MARKER_GPT4,
EXPENSIVE_MODEL_MARKER_OPUS,
Expand Down Expand Up @@ -268,7 +269,7 @@ def _check_prompt_length(self, token_estimate: float, issues: List, recommendati
{
"type": "long_prompt",
"message": "Prompt is very long, consider reducing context",
"severity": "warning",
"severity": Severity.WARNING.value,
}
)
recommendations.append("Consider extracting only relevant code sections")
Expand All @@ -291,7 +292,7 @@ def _check_prompt_redundancy(self, prompt: str, issues: List) -> None:
{
"type": "redundancy",
"message": f"Possible redundancy detected: {', '.join(repeated_words[:5])}",
"severity": "info",
"severity": Severity.INFO.value,
}
)

Expand Down
15 changes: 8 additions & 7 deletions autobot-backend/api/analytics_quality.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from auth_middleware import check_admin_permission
from autobot_shared.error_boundaries import ErrorCategory, with_error_handling
from autobot_shared.logging_manager import get_logger
from autobot_shared.status_enums import Severity
from autobot_shared.time_utils import now_utc, parse_utc_iso

logger = get_logger(__name__)
Expand Down Expand Up @@ -500,13 +501,13 @@ def _categorize_problems_for_patterns(
"""
# Count by type category
categories = {
"anti_pattern": {"count": 0, "severity": "high"},
"code_smell": {"count": 0, "severity": "medium"},
"best_practice": {"count": 0, "severity": "info"},
"security_vulnerability": {"count": 0, "severity": "critical"},
"performance_issue": {"count": 0, "severity": "high"},
"technical_debt": {"count": 0, "severity": "medium"},
"bug_risk": {"count": 0, "severity": "high"},
"anti_pattern": {"count": 0, "severity": Severity.HIGH.value},
"code_smell": {"count": 0, "severity": Severity.MEDIUM.value},
"best_practice": {"count": 0, "severity": Severity.INFO.value},
"security_vulnerability": {"count": 0, "severity": Severity.CRITICAL.value},
"performance_issue": {"count": 0, "severity": Severity.HIGH.value},
"technical_debt": {"count": 0, "severity": Severity.MEDIUM.value},
"bug_risk": {"count": 0, "severity": Severity.HIGH.value},
}

for problem in problems:
Expand Down
5 changes: 3 additions & 2 deletions autobot-backend/api/code_intelligence.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
from auth_middleware import check_admin_permission
from autobot_shared.error_boundaries import ErrorCategory, with_error_handling
from autobot_shared.logging_manager import get_logger
from autobot_shared.status_enums import Severity
from autobot_shared.time_utils import parse_utc_iso
from code_intelligence.anti_pattern_detector import (
AntiPatternDetector,
Expand Down Expand Up @@ -756,7 +757,7 @@ def _analyze_inline_code(request: CodeIntelAnalysisRequest) -> JSONResponse:
quality_score -= 10
issues.append(
{
"severity": "medium",
"severity": Severity.MEDIUM.value,
"category": "quality",
"message": "File exceeds 300 lines",
}
Expand All @@ -767,7 +768,7 @@ def _analyze_inline_code(request: CodeIntelAnalysisRequest) -> JSONResponse:
quality_score -= 5
issues.append(
{
"severity": "low",
"severity": Severity.LOW.value,
"category": "quality",
"message": "Average function length exceeds 50 lines",
}
Expand Down
7 changes: 4 additions & 3 deletions autobot-backend/api/codebase_analytics/analyzers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

from autobot_shared.logging_manager import get_logger
from autobot_shared.missing_dep import optional_import
from autobot_shared.status_enums import Severity
from constants.network_constants import NetworkConstants
from llm_shared.types import LLMType
from services.llm_service import get_llm_service
Expand Down Expand Up @@ -753,7 +754,7 @@ def _check_long_function(node: ast.FunctionDef) -> Dict | None:

return {
"type": "long_function",
"severity": "medium",
"severity": Severity.MEDIUM.value,
"line": node.lineno,
"description": f"Function '{node.name}' is {func_length} lines long",
"suggestion": "Consider breaking into smaller functions",
Expand Down Expand Up @@ -1528,7 +1529,7 @@ def _check_js_console_log(line: str, line_num: int) -> Dict | None:
if "console.log" in line and not line.strip().startswith("//"):
return {
"type": "debug_code",
"severity": "low",
"severity": Severity.LOW.value,
"line": line_num,
"description": "console.log statement found",
"suggestion": "Remove debug statements before production",
Expand Down Expand Up @@ -1562,7 +1563,7 @@ def _create_parse_error_result(error_msg: str) -> Metadata:
result["problems"] = [
{
"type": "parse_error",
"severity": "high",
"severity": Severity.HIGH.value,
"line": 1,
"description": f"Failed to parse file: {error_msg}",
"suggestion": "Check syntax errors",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import pytest

from autobot_shared.status_enums import Severity
from autobot_shared.time_utils import now_utc


Expand Down Expand Up @@ -399,7 +400,7 @@ def test_explicit_severity_preserved(self):
"value": "127.0.0.1",
"line": 1,
"file": "x.py",
"severity": "low", # override default
"severity": Severity.LOW.value, # override default
}
normalized = _normalize_hardcode_record(record)

Expand All @@ -423,7 +424,7 @@ def test_canonical_record_unchanged(self):
"value": "8001",
"line": 10,
"file": "app.py",
"severity": "medium",
"severity": Severity.MEDIUM.value,
"context": "PORT = 8001",
}
normalized = _normalize_hardcode_record(record)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from fastapi.testclient import TestClient

from api.codebase_analytics.endpoints.pattern_analysis import router
from autobot_shared.status_enums import Severity

_STORAGE_MODULE_NAME = "code_intelligence.pattern_analysis.storage"

Expand Down Expand Up @@ -92,7 +93,7 @@ def test_populated_store_returns_success(self, client, stub_storage):
mock_collection = AsyncMock()
mock_collection.get.return_value = {
"metadatas": [
{"pattern_type": "duplicate", "severity": "medium", "file_path": "a.py"},
{"pattern_type": "duplicate", "severity": Severity.MEDIUM.value, "file_path": "a.py"},
]
}
stub_storage.get_pattern_collection_async = AsyncMock(return_value=mock_collection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
from fastapi import HTTPException

from api import knowledge_grounding
from autobot_shared.status_enums import Severity

# The live wire shape: decode_responses=True means every field is already str.
DECODED_CONFLICTS = {
"conflict:abc123": {
"status": "pending",
"severity": "high",
"severity": Severity.HIGH.value,
"description": "KB says X, source says Y",
"timestamp": "1700000000.0",
},
Expand All @@ -39,7 +40,7 @@
BYTES_KEY_CONFLICTS = {
b"conflict:def456": {
"status": "pending",
"severity": "low",
"severity": Severity.LOW.value,
"description": "legacy bytes key",
"timestamp": "1700000001.0",
},
Expand Down
38 changes: 24 additions & 14 deletions autobot-backend/code_analysis/auto-tools/playwright_sanitizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,21 @@
from typing import Any, Dict, List, Tuple

from autobot_shared.logging_manager import get_logger
from autobot_shared.status_enums import Severity
from utils.line_index import LineIndex # #12884

# Issue #12660: auto-tools/ has no __init__.py (hyphenated dir name isn't a
# valid package identifier) — add this directory to sys.path so the shared
# tool skeleton can be imported by every standalone script here.
sys.path.insert(0, str(Path(__file__).resolve().parent))

from tool_base import ( # noqa: E402
SEVERITY_REPORT_ICONS,
SEVERITY_REPORT_ORDER,
severity_icon,
severity_label,
)

# Configure logging for security fixer
logging.basicConfig(level=logging.INFO, format="%(message)s")
logger = get_logger(__name__)
Expand Down Expand Up @@ -156,27 +169,27 @@ def scan_for_xss_patterns(self, content: str, file_path: str) -> List[Dict[str,
patterns = {
"innerHTML_usage": {
"regex": r"\.innerHTML\s*=\s*[^;]+",
"severity": "HIGH",
"severity": Severity.HIGH.value,
"description": "Direct innerHTML assignment detected",
},
"dangerouslySetInnerHTML": {
"regex": r"dangerouslySetInnerHTML\s*[=:]\s*\{[^}]*__html",
"severity": "HIGH",
"severity": Severity.HIGH.value,
"description": "React dangerouslySetInnerHTML usage detected",
},
"eval_usage": {
"regex": r"\beval\s*\(",
"severity": "CRITICAL",
"severity": Severity.CRITICAL.value,
"description": "eval() function usage detected",
},
"document_write": {
"regex": r"document\.write\s*\(",
"severity": "HIGH",
"severity": Severity.HIGH.value,
"description": "document.write() usage detected",
},
"javascript_protocol": {
"regex": r"javascript\s*:",
"severity": "MEDIUM",
"severity": Severity.MEDIUM.value,
"description": "javascript: protocol detected",
},
}
Expand Down Expand Up @@ -280,10 +293,8 @@ def _log_vuln_severity_summary(vulnerabilities: List[Dict[str, Any]]) -> None:
severity_counts: Dict[str, int] = {}
for vuln in vulnerabilities:
severity_counts[vuln["severity"]] = severity_counts.get(vuln["severity"], 0) + 1
severity_icons = {"CRITICAL": "🔴", "HIGH": "🟠", "MEDIUM": "🟡", "LOW": "🟢"}
for severity, count in severity_counts.items():
icon = severity_icons.get(severity, "⚪")
logger.info(" %s %s: %d patterns", icon, severity, count)
logger.info(" %s %s: %d patterns", severity_icon(severity), severity_label(severity), count)

def _apply_and_write_html(
self, original_content: str, original_size: int, file_path: str
Expand Down Expand Up @@ -403,7 +414,6 @@ def _build_vulnerability_analysis(self) -> str:
if not self.report["vulnerabilities"]:
return "✅ No vulnerability patterns detected in scanned files.\n\n"

severity_icons = {"CRITICAL": "🔴", "HIGH": "🟠", "MEDIUM": "🟡", "LOW": "🟢"}
severity_groups = {}
for vuln in self.report["vulnerabilities"]:
severity = vuln["severity"]
Expand All @@ -412,11 +422,11 @@ def _build_vulnerability_analysis(self) -> str:
severity_groups[severity].append(vuln)

content = "### Vulnerability Patterns by Severity:\n\n"
for severity in ["CRITICAL", "HIGH", "MEDIUM", "LOW"]:
if severity in severity_groups:
vulns = severity_groups[severity]
icon = severity_icons[severity]
content += f"#### {icon} {severity} ({len(vulns)} patterns)\n\n"
for level in SEVERITY_REPORT_ORDER:
if level.value in severity_groups:
vulns = severity_groups[level.value]
icon = SEVERITY_REPORT_ICONS[level]
content += f"#### {icon} {level.name} ({len(vulns)} patterns)\n\n"

for vuln in vulns:
content += f"- **{vuln['description']}**\n"
Expand Down
Loading
Loading