You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.9 KiB
140 lines
4.9 KiB
from datetime import datetime, timedelta
|
|
from typing import Any, Dict, Optional
|
|
|
|
from health import HealthCheck, HealthStatus
|
|
|
|
|
|
def check_motion_freshness(
|
|
conn: Any,
|
|
max_age_days: int = 7,
|
|
min_motions: int = 100,
|
|
) -> HealthCheck:
|
|
try:
|
|
result = conn.execute(
|
|
"SELECT COUNT(*) FROM motions WHERE date >= ?",
|
|
[datetime.now() - timedelta(days=max_age_days)],
|
|
).fetchone()
|
|
count = result[0] if result else 0
|
|
except Exception as e:
|
|
return HealthCheck(
|
|
name="motion_freshness",
|
|
status=HealthStatus.CRITICAL,
|
|
message=f"Could not query motion freshness: {e}",
|
|
details={},
|
|
)
|
|
|
|
if count == 0:
|
|
return HealthCheck(
|
|
name="motion_freshness",
|
|
status=HealthStatus.CRITICAL,
|
|
message=f"No motions in last {max_age_days} days",
|
|
details={"count": 0, "threshold": max_age_days},
|
|
)
|
|
if count < min_motions:
|
|
return HealthCheck(
|
|
name="motion_freshness",
|
|
status=HealthStatus.WARNING,
|
|
message=f"Only {count} motions in last {max_age_days} days (expected >= {min_motions})",
|
|
details={"count": count, "threshold": max_age_days, "min_expected": min_motions},
|
|
)
|
|
return HealthCheck(
|
|
name="motion_freshness",
|
|
status=HealthStatus.OK,
|
|
message=f"{count} motions in last {max_age_days} days",
|
|
details={"count": count, "threshold": max_age_days},
|
|
)
|
|
|
|
|
|
def check_embedding_coverage(
|
|
conn: Any,
|
|
min_coverage: float = 0.95,
|
|
) -> HealthCheck:
|
|
try:
|
|
total_result = conn.execute("SELECT COUNT(*) FROM motions").fetchone()
|
|
total = total_result[0] if total_result else 0
|
|
|
|
if total == 0:
|
|
return HealthCheck(
|
|
name="embedding_coverage",
|
|
status=HealthStatus.CRITICAL,
|
|
message="No motions in database",
|
|
details={"total": 0, "with_embeddings": 0, "coverage": 0.0},
|
|
)
|
|
|
|
embed_result = conn.execute(
|
|
"SELECT COUNT(DISTINCT motion_id) FROM fused_embeddings"
|
|
).fetchone()
|
|
with_embeddings = embed_result[0] if embed_result else 0
|
|
coverage = with_embeddings / total
|
|
except Exception as e:
|
|
return HealthCheck(
|
|
name="embedding_coverage",
|
|
status=HealthStatus.CRITICAL,
|
|
message=f"Could not query embedding coverage: {e}",
|
|
details={},
|
|
)
|
|
|
|
if coverage < min_coverage:
|
|
return HealthCheck(
|
|
name="embedding_coverage",
|
|
status=HealthStatus.WARNING,
|
|
message=f"Embedding coverage {coverage:.1%} (expected >= {min_coverage:.0%})",
|
|
details={"total": total, "with_embeddings": with_embeddings, "coverage": coverage},
|
|
)
|
|
return HealthCheck(
|
|
name="embedding_coverage",
|
|
status=HealthStatus.OK,
|
|
message=f"Embedding coverage {coverage:.1%}",
|
|
details={"total": total, "with_embeddings": with_embeddings, "coverage": coverage},
|
|
)
|
|
|
|
|
|
def check_llm_coverage(
|
|
conn: Any,
|
|
max_missing_ratio: float = 0.15,
|
|
) -> HealthCheck:
|
|
try:
|
|
total_result = conn.execute("SELECT COUNT(*) FROM motions").fetchone()
|
|
total = total_result[0] if total_result else 0
|
|
|
|
if total == 0:
|
|
return HealthCheck(
|
|
name="llm_coverage",
|
|
status=HealthStatus.CRITICAL,
|
|
message="No motions in database",
|
|
details={"total": 0, "missing": 0, "missing_ratio": 0.0},
|
|
)
|
|
|
|
missing_result = conn.execute(
|
|
"SELECT COUNT(*) FROM motions WHERE layman_explanation IS NULL OR layman_explanation = ''"
|
|
).fetchone()
|
|
missing = missing_result[0] if missing_result else 0
|
|
missing_ratio = missing / total
|
|
except Exception as e:
|
|
return HealthCheck(
|
|
name="llm_coverage",
|
|
status=HealthStatus.CRITICAL,
|
|
message=f"Could not query LLM coverage: {e}",
|
|
details={},
|
|
)
|
|
|
|
if missing_ratio > max_missing_ratio:
|
|
return HealthCheck(
|
|
name="llm_coverage",
|
|
status=HealthStatus.CRITICAL,
|
|
message=f"{missing_ratio:.1%} missing layman explanations ({missing}/{total})",
|
|
details={"total": total, "missing": missing, "missing_ratio": missing_ratio},
|
|
)
|
|
if missing_ratio > 0.05:
|
|
return HealthCheck(
|
|
name="llm_coverage",
|
|
status=HealthStatus.WARNING,
|
|
message=f"{missing_ratio:.1%} missing layman explanations ({missing}/{total})",
|
|
details={"total": total, "missing": missing, "missing_ratio": missing_ratio},
|
|
)
|
|
return HealthCheck(
|
|
name="llm_coverage",
|
|
status=HealthStatus.OK,
|
|
message=f"{missing_ratio:.1%} missing layman explanations ({missing}/{total})",
|
|
details={"total": total, "missing": missing, "missing_ratio": missing_ratio},
|
|
)
|
|
|