안전 이벤트 대시보드 보강

This commit is contained in:
Yun Chan 2026-07-01 12:34:46 +09:00
parent fe2796f05a
commit 51053af536
15 changed files with 1081 additions and 423 deletions

View file

@ -7,7 +7,7 @@
from __future__ import annotations
from enum import Enum
import json
import logging
from typing import Optional
from . import db, session_persistence
@ -17,6 +17,8 @@ from .services import guardrail, orchestrator, state_machine
from .stage_contract import stage_label
from .store import InProcSession, TurnRecord, store
logger = logging.getLogger(__name__)
class SessionAccessError(str, Enum):
NOT_FOUND = "not_found"
@ -147,8 +149,16 @@ async def record_safety_event(
if crisis is None or not getattr(crisis, "escalate", False):
return
kind = getattr(crisis.kind, "value", None) or str(getattr(crisis, "kind", "crisis"))
detail = {
"matched": list(getattr(crisis, "matched", []) or []),
"stage": getattr(result, "stage", None),
"turn_seq": getattr(result, "turn_seq", None),
"conversation_stopped": getattr(result, "conversation_stopped", False),
"crisis_resource": getattr(result, "crisis_resource", None),
"alert_status": "teacher_dashboard",
}
try:
async with db.acquire() as conn:
async with db.acquire(ai_context=True) as conn:
await conn.execute(
"""
INSERT INTO app.safety_events
@ -158,17 +168,15 @@ async def record_safety_event(
sess.session_id,
kind,
int(getattr(crisis, "risk_level", 0) or 0),
json.dumps({
"matched": list(getattr(crisis, "matched", []) or []),
"stage": getattr(result, "stage", None),
"turn_seq": getattr(result, "turn_seq", None),
"conversation_stopped": getattr(result, "conversation_stopped", False),
"crisis_resource": getattr(result, "crisis_resource", None),
"alert_status": "teacher_dashboard",
}),
detail,
)
except Exception:
pass
logger.exception(
"safety event persistence failed: session_id=%s trigger_type=%s",
sess.session_id,
kind,
)
require_runtime_fallback_allowed("safety event")
async def finalize_completed_turn(