fix(api): include auto repair executions in AI stats
All checks were successful
Code Review / ai-code-review (push) Successful in 14s
CD Pipeline / tests (push) Successful in 1m36s
CD Pipeline / build-and-deploy (push) Successful in 4m55s
CD Pipeline / post-deploy-checks (push) Successful in 1m34s

This commit is contained in:
Your Name
2026-06-27 16:01:54 +08:00
parent 37620ef8ad
commit 9132525d3c
3 changed files with 76 additions and 4 deletions

View File

@@ -122,6 +122,11 @@ class AIPerformance(BaseModel):
effectiveness_distribution: dict[int, int] = Field(
description="有效性評分分佈 {1: count, 2: count, ...}"
)
outcome_proposal_count: int = Field(default=0, description="Incident outcome 舊提案數")
outcome_executed_count: int = Field(default=0, description="Incident outcome 舊執行數")
auto_repair_total: int = Field(default=0, description="自動修復執行紀錄數")
auto_repair_success: int = Field(default=0, description="自動修復成功紀錄數")
source: str = Field(default="incident_outcome", description="AI 效能資料來源")
class ServiceImpact(BaseModel):

View File

@@ -27,7 +27,7 @@ from sqlalchemy import func, select
from src.core.redis_client import get_redis
from src.db.base import get_db_context
from src.db.models import IncidentRecord
from src.db.models import AutoRepairExecution, IncidentRecord
from src.models.incident import IncidentStatus
logger = structlog.get_logger(__name__)
@@ -343,12 +343,26 @@ class StatsService:
)
outcomes = [row[0] for row in result.all() if row[0]]
total = len(outcomes)
executed = sum(1 for o in outcomes if o.get("proposal_executed"))
success = sum(
outcome_total = len(outcomes)
outcome_executed = sum(1 for o in outcomes if o.get("proposal_executed"))
outcome_success = sum(
1 for o in outcomes if o.get("proposal_executed") and o.get("execution_success")
)
auto_result = await db.execute(
select(
AutoRepairExecution.success,
AutoRepairExecution.execution_time_ms,
).where(AutoRepairExecution.created_at >= since)
)
auto_rows = auto_result.all()
auto_total = len(auto_rows)
auto_success = sum(1 for row in auto_rows if row[0] is True)
total = max(outcome_total, auto_total)
executed = max(outcome_executed, auto_total)
success = auto_success if auto_total > 0 else outcome_success
effectiveness_dist: dict[int, int] = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
scores = []
for o in outcomes:
@@ -367,6 +381,13 @@ class StatsService:
"success_rate": round((success / executed * 100) if executed > 0 else 0, 2),
"avg_effectiveness": round(avg_effectiveness, 2) if avg_effectiveness else None,
"effectiveness_distribution": effectiveness_dist,
"outcome_proposal_count": outcome_total,
"outcome_executed_count": outcome_executed,
"auto_repair_total": auto_total,
"auto_repair_success": auto_success,
"source": "auto_repair_executions+incident_outcome"
if auto_total > 0
else "incident_outcome",
}
return await self.get_cached_or_compute(cache_key, compute)