Implement Manticore fully and re-theme

This commit is contained in:
2026-03-11 02:19:08 +00:00
parent da044be68c
commit cbedcd67f6
46 changed files with 3444 additions and 944 deletions

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from dataclasses import dataclass
from core.events.manticore import get_session_event_rows
from core.models import ChatSession, ConversationEvent, Message
@@ -59,27 +60,56 @@ def _normalize_reactions(rows: list[dict] | None) -> list[dict]:
)
def project_session_from_events(session: ChatSession) -> list[dict]:
rows = list(
ConversationEvent.objects.filter(
user=session.user,
session=session,
).order_by("ts", "created_at")
def _event_rows_for_session(session: ChatSession):
try:
rows = get_session_event_rows(
user_id=int(session.user_id),
session_id=str(session.id),
limit=2000,
)
except Exception:
rows = []
if rows:
return rows, "manticore"
return (
list(
ConversationEvent.objects.filter(
user=session.user,
session=session,
).order_by("ts", "created_at")
),
"django",
)
def project_session_from_events(session: ChatSession) -> list[dict]:
rows, _source = _event_rows_for_session(session)
projected: dict[str, _ProjectedMessage] = {}
order: list[str] = []
for event in rows:
payload = dict(event.payload or {})
event_type = str(event.event_type or "").strip().lower()
is_dict = isinstance(event, dict)
payload = dict(
(event.get("payload") if is_dict else getattr(event, "payload", {})) or {}
)
event_type = str(
(event.get("event_type") if is_dict else getattr(event, "event_type", ""))
or ""
).strip().lower()
message_id = str(
payload.get("message_id") or payload.get("target_message_id") or ""
).strip()
if event_type == "message_created":
message_id = str(
payload.get("message_id") or event.origin_message_id or ""
payload.get("message_id")
or (
event.get("origin_message_id")
if is_dict
else getattr(event, "origin_message_id", "")
)
or ""
).strip()
if not message_id:
continue
@@ -88,10 +118,14 @@ def project_session_from_events(session: ChatSession) -> list[dict]:
state = _ProjectedMessage(message_id=message_id)
projected[message_id] = state
order.append(message_id)
state.ts = _safe_int(payload.get("message_ts"), _safe_int(event.ts))
state.ts = _safe_int(
payload.get("message_ts"),
_safe_int(event.get("ts") if is_dict else getattr(event, "ts", 0)),
)
state.text = str(payload.get("text") or state.text or "")
delivered_default = _safe_int(
payload.get("delivered_ts"), _safe_int(event.ts)
payload.get("delivered_ts"),
_safe_int(event.get("ts") if is_dict else getattr(event, "ts", 0)),
)
if state.delivered_ts is None:
state.delivered_ts = delivered_default or None
@@ -102,7 +136,10 @@ def project_session_from_events(session: ChatSession) -> list[dict]:
state = projected[message_id]
if event_type == "read_receipt":
read_ts = _safe_int(payload.get("read_ts"), _safe_int(event.ts))
read_ts = _safe_int(
payload.get("read_ts"),
_safe_int(event.get("ts") if is_dict else getattr(event, "ts", 0)),
)
if read_ts > 0:
if state.read_ts is None:
state.read_ts = read_ts
@@ -114,11 +151,27 @@ def project_session_from_events(session: ChatSession) -> list[dict]:
if event_type in {"reaction_added", "reaction_removed"}:
source_service = (
str(payload.get("source_service") or event.origin_transport or "")
str(
payload.get("source_service")
or (
event.get("origin_transport")
if is_dict
else getattr(event, "origin_transport", "")
)
or ""
)
.strip()
.lower()
)
actor = str(payload.get("actor") or event.actor_identifier or "").strip()
actor = str(
payload.get("actor")
or (
event.get("actor_identifier")
if is_dict
else getattr(event, "actor_identifier", "")
)
or ""
).strip()
emoji = str(payload.get("emoji") or "").strip()
if not source_service and not actor and not emoji:
continue