Implement Manticore fully and re-theme
This commit is contained in:
@@ -7,6 +7,12 @@ from django.urls import reverse
|
||||
from django.views import View
|
||||
|
||||
from core.clients import transport
|
||||
from core.events.manticore import (
|
||||
count_behavioral_events,
|
||||
get_recent_event_rows,
|
||||
get_trace_event_rows,
|
||||
get_trace_ids,
|
||||
)
|
||||
from core.events.projection import shadow_compare_session
|
||||
from core.memory.search_backend import backend_status, get_memory_search_backend
|
||||
from core.models import (
|
||||
@@ -56,12 +62,20 @@ class SystemSettings(SuperUserRequiredMixin, View):
|
||||
template_name = "pages/system-settings.html"
|
||||
|
||||
def _counts(self, user):
|
||||
behavioral_event_rows = 0
|
||||
try:
|
||||
behavioral_event_rows = int(count_behavioral_events(user_id=int(user.id)) or 0)
|
||||
except Exception:
|
||||
behavioral_event_rows = 0
|
||||
return {
|
||||
"chat_sessions": ChatSession.objects.filter(user=user).count(),
|
||||
"messages": Message.objects.filter(user=user).count(),
|
||||
"queued_messages": QueuedMessage.objects.filter(user=user).count(),
|
||||
"message_events": MessageEvent.objects.filter(user=user).count(),
|
||||
"conversation_events": ConversationEvent.objects.filter(user=user).count(),
|
||||
"conversation_event_shadow_rows": ConversationEvent.objects.filter(
|
||||
user=user
|
||||
).count(),
|
||||
"behavioral_event_rows": behavioral_event_rows,
|
||||
"adapter_health_events": AdapterHealthEvent.objects.filter(
|
||||
user=user
|
||||
).count(),
|
||||
@@ -203,6 +217,21 @@ class SystemSettings(SuperUserRequiredMixin, View):
|
||||
trace_options.append(value)
|
||||
if len(trace_options) >= 120:
|
||||
break
|
||||
if len(trace_options) < 120:
|
||||
try:
|
||||
for trace_id in get_trace_ids(
|
||||
user_id=int(user.id),
|
||||
limit=max(1, 120 - len(trace_options)),
|
||||
):
|
||||
value = str(trace_id or "").strip()
|
||||
if not value or value in seen_trace_ids:
|
||||
continue
|
||||
seen_trace_ids.add(value)
|
||||
trace_options.append(value)
|
||||
if len(trace_options) >= 120:
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
service_candidates = {"signal", "whatsapp", "xmpp", "instagram", "web"}
|
||||
service_candidates.update(
|
||||
@@ -212,6 +241,18 @@ class SystemSettings(SuperUserRequiredMixin, View):
|
||||
.values_list("origin_transport", flat=True)
|
||||
.distinct()[:50]
|
||||
)
|
||||
try:
|
||||
service_candidates.update(
|
||||
str(item.get("origin_transport") or "").strip().lower()
|
||||
for item in get_recent_event_rows(
|
||||
minutes=60 * 24 * 30,
|
||||
user_id=str(user.id),
|
||||
limit=500,
|
||||
)
|
||||
if str(item.get("origin_transport") or "").strip()
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
service_options = sorted(value for value in service_candidates if value)
|
||||
|
||||
event_type_candidates = {
|
||||
@@ -229,6 +270,18 @@ class SystemSettings(SuperUserRequiredMixin, View):
|
||||
.values_list("event_type", flat=True)
|
||||
.distinct()[:80]
|
||||
)
|
||||
try:
|
||||
event_type_candidates.update(
|
||||
str(item.get("event_type") or "").strip().lower()
|
||||
for item in get_recent_event_rows(
|
||||
minutes=60 * 24 * 30,
|
||||
user_id=str(user.id),
|
||||
limit=500,
|
||||
)
|
||||
if str(item.get("event_type") or "").strip()
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
event_type_options = sorted(value for value in event_type_candidates if value)
|
||||
|
||||
return {
|
||||
@@ -306,10 +359,26 @@ class TraceDiagnosticsAPI(SuperUserRequiredMixin, View):
|
||||
.select_related("session")
|
||||
.order_by("ts", "created_at")[:500]
|
||||
)
|
||||
data_source = "django"
|
||||
if not rows:
|
||||
try:
|
||||
rows = get_trace_event_rows(
|
||||
user_id=int(request.user.id),
|
||||
trace_id=trace_id,
|
||||
limit=500,
|
||||
)
|
||||
except Exception:
|
||||
rows = []
|
||||
if rows:
|
||||
data_source = "manticore"
|
||||
related_session_ids = []
|
||||
seen_sessions = set()
|
||||
for row in rows:
|
||||
session_id = str(row.session_id or "").strip()
|
||||
session_id = (
|
||||
str(row.session_id or "").strip()
|
||||
if not isinstance(row, dict)
|
||||
else str(row.get("session_id") or "").strip()
|
||||
)
|
||||
if not session_id or session_id in seen_sessions:
|
||||
continue
|
||||
seen_sessions.add(session_id)
|
||||
@@ -319,6 +388,7 @@ class TraceDiagnosticsAPI(SuperUserRequiredMixin, View):
|
||||
{
|
||||
"ok": True,
|
||||
"trace_id": trace_id,
|
||||
"data_source": data_source,
|
||||
"count": len(rows),
|
||||
"related_session_ids": related_session_ids,
|
||||
"projection_shadow_urls": [
|
||||
@@ -327,19 +397,56 @@ class TraceDiagnosticsAPI(SuperUserRequiredMixin, View):
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"id": str(row.id),
|
||||
"ts": int(row.ts or 0),
|
||||
"event_type": str(row.event_type or ""),
|
||||
"direction": str(row.direction or ""),
|
||||
"session_id": str(row.session_id or ""),
|
||||
"id": (
|
||||
str(row.id)
|
||||
if not isinstance(row, dict)
|
||||
else str(row.get("id") or "")
|
||||
),
|
||||
"ts": (
|
||||
int(row.ts or 0)
|
||||
if not isinstance(row, dict)
|
||||
else int(row.get("ts") or 0)
|
||||
),
|
||||
"event_type": (
|
||||
str(row.event_type or "")
|
||||
if not isinstance(row, dict)
|
||||
else str(row.get("event_type") or "")
|
||||
),
|
||||
"direction": (
|
||||
str(row.direction or "")
|
||||
if not isinstance(row, dict)
|
||||
else str(row.get("direction") or "")
|
||||
),
|
||||
"session_id": (
|
||||
str(row.session_id or "")
|
||||
if not isinstance(row, dict)
|
||||
else str(row.get("session_id") or "")
|
||||
),
|
||||
"projection_shadow_url": (
|
||||
f"{reverse('system_projection_shadow')}?session_id={str(row.session_id or '').strip()}"
|
||||
if str(row.session_id or "").strip()
|
||||
f"{reverse('system_projection_shadow')}?session_id="
|
||||
f"{(str(row.session_id or '').strip() if not isinstance(row, dict) else str(row.get('session_id') or '').strip())}"
|
||||
if (
|
||||
str(row.session_id or "").strip()
|
||||
if not isinstance(row, dict)
|
||||
else str(row.get("session_id") or "").strip()
|
||||
)
|
||||
else ""
|
||||
),
|
||||
"origin_transport": str(row.origin_transport or ""),
|
||||
"origin_message_id": str(row.origin_message_id or ""),
|
||||
"payload": dict(row.payload or {}),
|
||||
"origin_transport": (
|
||||
str(row.origin_transport or "")
|
||||
if not isinstance(row, dict)
|
||||
else str(row.get("origin_transport") or "")
|
||||
),
|
||||
"origin_message_id": (
|
||||
str(row.origin_message_id or "")
|
||||
if not isinstance(row, dict)
|
||||
else str(row.get("origin_message_id") or "")
|
||||
),
|
||||
"payload": (
|
||||
dict(row.payload or {})
|
||||
if not isinstance(row, dict)
|
||||
else dict(row.get("payload") or {})
|
||||
),
|
||||
}
|
||||
for row in rows
|
||||
],
|
||||
@@ -377,18 +484,7 @@ class EventProjectionShadowAPI(SuperUserRequiredMixin, View):
|
||||
|
||||
|
||||
class EventLedgerSmokeAPI(SuperUserRequiredMixin, View):
|
||||
def get(self, request):
|
||||
minutes = max(1, int(request.GET.get("minutes") or 120))
|
||||
service = str(request.GET.get("service") or "").strip().lower()
|
||||
user_id = str(request.GET.get("user_id") or "").strip() or str(request.user.id)
|
||||
limit = max(1, min(500, int(request.GET.get("limit") or 200)))
|
||||
require_types_raw = str(request.GET.get("require_types") or "").strip()
|
||||
required_types = [
|
||||
item.strip().lower()
|
||||
for item in require_types_raw.split(",")
|
||||
if item.strip()
|
||||
]
|
||||
|
||||
def _recent_rows(self, *, minutes: int, service: str, user_id: str, limit: int):
|
||||
cutoff_ts = int(time.time() * 1000) - (minutes * 60 * 1000)
|
||||
queryset = ConversationEvent.objects.filter(ts__gte=cutoff_ts).order_by("-ts")
|
||||
if service:
|
||||
@@ -408,6 +504,37 @@ class EventLedgerSmokeAPI(SuperUserRequiredMixin, View):
|
||||
"trace_id",
|
||||
)[:limit]
|
||||
)
|
||||
if rows:
|
||||
return rows, "django"
|
||||
try:
|
||||
manticore_rows = get_recent_event_rows(
|
||||
minutes=minutes,
|
||||
service=service,
|
||||
user_id=user_id,
|
||||
limit=limit,
|
||||
)
|
||||
except Exception:
|
||||
manticore_rows = []
|
||||
return manticore_rows, "manticore" if manticore_rows else "django"
|
||||
|
||||
def get(self, request):
|
||||
minutes = max(1, int(request.GET.get("minutes") or 120))
|
||||
service = str(request.GET.get("service") or "").strip().lower()
|
||||
user_id = str(request.GET.get("user_id") or "").strip() or str(request.user.id)
|
||||
limit = max(1, min(500, int(request.GET.get("limit") or 200)))
|
||||
require_types_raw = str(request.GET.get("require_types") or "").strip()
|
||||
required_types = [
|
||||
item.strip().lower()
|
||||
for item in require_types_raw.split(",")
|
||||
if item.strip()
|
||||
]
|
||||
|
||||
rows, data_source = self._recent_rows(
|
||||
minutes=minutes,
|
||||
service=service,
|
||||
user_id=user_id,
|
||||
limit=limit,
|
||||
)
|
||||
event_type_counts = {}
|
||||
for row in rows:
|
||||
key = str(row.get("event_type") or "")
|
||||
@@ -423,6 +550,7 @@ class EventLedgerSmokeAPI(SuperUserRequiredMixin, View):
|
||||
"minutes": minutes,
|
||||
"service": service,
|
||||
"user_id": user_id,
|
||||
"data_source": data_source,
|
||||
"count": len(rows),
|
||||
"event_type_counts": event_type_counts,
|
||||
"required_types": required_types,
|
||||
|
||||
Reference in New Issue
Block a user