fix(awooop): cache heavy operator summaries
This commit is contained in:
@@ -9,6 +9,7 @@ ADR-106(AwoooP Agent Platform)
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import uuid
|
||||
@@ -59,6 +60,10 @@ from src.services.ollama_failover_manager import (
|
||||
)
|
||||
from src.services.ollama_health_monitor import HealthReport, HealthStatus
|
||||
from src.services.operator_outcome import build_operator_outcome
|
||||
from src.services.operator_summary_cache import (
|
||||
get_cached_operator_summary,
|
||||
store_operator_summary,
|
||||
)
|
||||
from src.services.run_state_machine import transition
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
@@ -74,6 +79,9 @@ _MAX_STEP_SUMMARY_CHARS = 128
|
||||
_AI_ROUTE_STATUS_SELECT_TIMEOUT_SECONDS = 12.0
|
||||
_AI_ROUTE_STATUS_CONNECTIVITY_TIMEOUT_SECONDS = 2.5
|
||||
_REMEDIATION_HISTORY_LIMIT = 20
|
||||
_CALLBACK_REPLY_CACHE_TTL_SECONDS = int(
|
||||
os.getenv("AWOOOP_CALLBACK_REPLY_CACHE_TTL_SECONDS", "20")
|
||||
)
|
||||
_INCIDENT_ID_RE = re.compile(r"\bINC-\d{8}-[A-Z0-9]{4,}\b")
|
||||
_REMEDIATION_STATUS_FILTERS = {
|
||||
"mcp_observed",
|
||||
@@ -304,11 +312,13 @@ async def list_callback_replies(
|
||||
incident_id: str | None,
|
||||
page: int,
|
||||
per_page: int,
|
||||
refresh: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
"""列出 Telegram detail/history callback reply evidence,不改 runtime 狀態。"""
|
||||
_validate_callback_reply_status_filter(callback_reply_status)
|
||||
callback_action = _validate_callback_reply_action_filter(action)
|
||||
_validate_incident_id_filter(incident_id)
|
||||
normalized_project_id = project_id or "awoooi"
|
||||
|
||||
if callback_reply_status == "no_callback":
|
||||
return {
|
||||
@@ -318,6 +328,33 @@ async def list_callback_replies(
|
||||
"per_page": per_page,
|
||||
}
|
||||
|
||||
cache_key = {
|
||||
"project_id": project_id or "__all__",
|
||||
"callback_reply_status": callback_reply_status or "",
|
||||
"action": callback_action or "",
|
||||
"incident_id": incident_id or "",
|
||||
"page": page,
|
||||
"per_page": per_page,
|
||||
}
|
||||
if not refresh:
|
||||
cached_response = get_cached_operator_summary(
|
||||
"callback_replies",
|
||||
cache_key,
|
||||
ttl_seconds=_CALLBACK_REPLY_CACHE_TTL_SECONDS,
|
||||
)
|
||||
if cached_response is not None:
|
||||
logger.info(
|
||||
"operator_callback_replies_cache_hit",
|
||||
project_id=normalized_project_id,
|
||||
callback_reply_status=callback_reply_status,
|
||||
action=callback_action,
|
||||
incident_id=incident_id,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
ttl_seconds=_CALLBACK_REPLY_CACHE_TTL_SECONDS,
|
||||
)
|
||||
return cached_response
|
||||
|
||||
where_clauses = [
|
||||
"m.source_envelope ? 'callback_reply'",
|
||||
]
|
||||
@@ -399,14 +436,14 @@ async def list_callback_replies(
|
||||
LIMIT :limit OFFSET :offset
|
||||
""")
|
||||
|
||||
async with get_db_context(project_id or "awoooi") as db:
|
||||
async with get_db_context(normalized_project_id) as db:
|
||||
count_result = await db.execute(count_sql, params)
|
||||
total = count_result.scalar_one()
|
||||
rows_result = await db.execute(list_sql, params)
|
||||
rows = list(rows_result.mappings().all())
|
||||
audit_summary = await _fetch_callback_reply_audit_summary(
|
||||
db,
|
||||
project_id=project_id or "awoooi",
|
||||
project_id=normalized_project_id,
|
||||
)
|
||||
|
||||
items = [_callback_reply_event_item(row) for row in rows]
|
||||
@@ -459,13 +496,31 @@ async def list_callback_replies(
|
||||
km_completion_summary_cache[summary_cache_key] = km_summary
|
||||
item["km_stale_completion_summary"] = km_summary
|
||||
|
||||
return {
|
||||
response = {
|
||||
"items": items,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"per_page": per_page,
|
||||
"summary": audit_summary,
|
||||
}
|
||||
logger.info(
|
||||
"operator_callback_replies_fetched",
|
||||
project_id=normalized_project_id,
|
||||
callback_reply_status=callback_reply_status,
|
||||
action=callback_action,
|
||||
incident_id=incident_id,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
total=total,
|
||||
cache_status="miss",
|
||||
cache_ttl_seconds=_CALLBACK_REPLY_CACHE_TTL_SECONDS,
|
||||
)
|
||||
return store_operator_summary(
|
||||
"callback_replies",
|
||||
cache_key,
|
||||
response,
|
||||
ttl_seconds=_CALLBACK_REPLY_CACHE_TTL_SECONDS,
|
||||
)
|
||||
|
||||
|
||||
async def _fetch_callback_reply_audit_summary(
|
||||
|
||||
Reference in New Issue
Block a user