Compare commits

...

1 Commits

Author SHA1 Message Date
f4646944b7 fix: crisis hook only warns on high confidence (#711)
Some checks failed
Contributor Attribution Check / check-attribution (pull_request) Failing after 1m7s
Docker Build and Publish / build-and-push (pull_request) Has been skipped
Supply Chain Audit / Scan PR for supply chain risks (pull_request) Successful in 50s
Tests / e2e (pull_request) Successful in 3m14s
Tests / test (pull_request) Failing after 54m34s
Crisis detection hook logs WARNING only for critical/high severity
(crisis is_crisis=True). Medium/low confidence signals log at INFO
to avoid log noise.

Changes:
- gateway/builtin_hooks/crisis_detection.py: New builtin hook
  that checks user messages on agent:start event
- gateway/hooks.py: Register crisis-detection hook in
  _register_builtin_hooks()

Behavior:
- Critical/high (is_crisis=True) → logger.warning()
- Medium (low confidence) → logger.info()
- No match → no log

Closes #711.
2026-04-15 21:35:38 -04:00
2 changed files with 64 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
"""
Crisis detection hook — monitors user messages for crisis signals.
Fires on agent:start event to check incoming user messages for crisis
signals. Only logs WARNING for high-confidence matches (critical/high
severity). Lower-confidence signals log at INFO level to avoid noise.
Refs: #702, #711
"""
import logging
logger = logging.getLogger(__name__)
async def handle(event_type: str, context: dict) -> None:
"""Check user message for crisis signals on agent:start."""
if event_type != "agent:start":
return
user_message = context.get("user_message", "")
if not user_message or not user_message.strip():
return
try:
from tools.crisis_detection import check_crisis
except ImportError:
return
result = check_crisis(user_message)
if not result.matched_patterns:
return
# Only log WARNING for high-confidence crisis signals
# Lower-confidence matches (medium) log at INFO to avoid log noise
if result.is_crisis:
logger.warning(
"crisis detected: severity=%s lang=%s patterns=%d session=%s",
result.severity,
result.language,
len(result.matched_patterns),
context.get("session_id", "unknown"),
)
else:
logger.info(
"crisis signal (low confidence): severity=%s lang=%s patterns=%d",
result.severity,
result.language,
len(result.matched_patterns),
)

View File

@@ -66,6 +66,19 @@ class HookRegistry:
except Exception as e:
print(f"[hooks] Could not load built-in boot-md hook: {e}", flush=True)
try:
from gateway.builtin_hooks.crisis_detection import handle as crisis_handle
self._handlers.setdefault("agent:start", []).append(crisis_handle)
self._loaded_hooks.append({
"name": "crisis-detection",
"description": "Monitor user messages for crisis signals (warns only on high confidence)",
"events": ["agent:start"],
"path": "(builtin)",
})
except Exception as e:
print(f"[hooks] Could not load built-in crisis-detection hook: {e}", flush=True)
def discover_and_load(self) -> None:
"""
Scan the hooks directory for hook directories and load their handlers.