mirror of
https://github.com/open-webui/open-webui.git
synced 2026-06-14 03:30:25 +00:00
refac
This commit is contained in:
@@ -394,6 +394,24 @@ class ChatMessageTable:
|
||||
await db.commit()
|
||||
return True
|
||||
|
||||
async def delete_message_ids_by_chat_id(
|
||||
self,
|
||||
chat_id: str,
|
||||
message_ids: set[str],
|
||||
db: Optional[AsyncSession] = None,
|
||||
) -> bool:
|
||||
"""Delete specific ``chat_message`` rows by their original message IDs."""
|
||||
if not message_ids:
|
||||
return True
|
||||
async with get_async_db_context(db) as db:
|
||||
await db.execute(
|
||||
delete(ChatMessage)
|
||||
.where(ChatMessage.chat_id == chat_id)
|
||||
.where(ChatMessage.id.in_({f'{chat_id}-{mid}' for mid in message_ids}))
|
||||
)
|
||||
await db.commit()
|
||||
return True
|
||||
|
||||
# Analytics methods
|
||||
async def get_message_count_by_model(
|
||||
self,
|
||||
|
||||
@@ -394,6 +394,9 @@ class ChatTable:
|
||||
try:
|
||||
async with get_async_db_context(db) as db:
|
||||
chat_item = await db.get(Chat, id)
|
||||
if chat_item is None:
|
||||
return None
|
||||
|
||||
chat_item.chat = self._clean_null_bytes(chat)
|
||||
chat_item.title = self._clean_null_bytes(chat['title']) if 'title' in chat else 'New Chat'
|
||||
|
||||
@@ -495,6 +498,26 @@ class ChatTable:
|
||||
except Exception as e:
|
||||
log.warning('Backfill failed for message %s in chat %s: %s', message_id, chat_id, e)
|
||||
|
||||
async def reconcile_messages_by_chat_id(
|
||||
self, chat_id: str, user_id: str, messages: dict[str, dict]
|
||||
) -> None:
|
||||
"""Sync ``chat_message`` rows with the committed JSON blob.
|
||||
|
||||
Upserts current messages via ``backfill_messages_by_chat_id``
|
||||
and deletes orphaned rows whose message_id no longer appears
|
||||
in the blob. Best-effort: errors are logged but never raised.
|
||||
"""
|
||||
try:
|
||||
await self.backfill_messages_by_chat_id(chat_id, user_id, messages)
|
||||
|
||||
existing_map = await ChatMessages.get_messages_map_by_chat_id(chat_id)
|
||||
if existing_map is not None:
|
||||
orphaned_ids = set(existing_map.keys()) - set(messages.keys())
|
||||
if orphaned_ids:
|
||||
await ChatMessages.delete_message_ids_by_chat_id(chat_id, orphaned_ids)
|
||||
except Exception as e:
|
||||
log.warning('Failed to reconcile chat_message rows for chat %s: %s', chat_id, e)
|
||||
|
||||
async def get_messages_map_by_chat_id(self, id: str) -> dict | None:
|
||||
"""Message map for walking history (see ``get_message_list``).
|
||||
|
||||
|
||||
@@ -987,6 +987,14 @@ async def update_chat_by_id(
|
||||
msg['content'] = serialize_output(msg['output'])
|
||||
|
||||
chat = await Chats.update_chat_by_id(id, updated_chat, db=db)
|
||||
|
||||
# Reconcile chat_message rows with the committed blob.
|
||||
# This is the only caller where the frontend pushes a full
|
||||
# history with potential edits, deletions, or new branches.
|
||||
messages = (updated_chat.get('history') or {}).get('messages') or {}
|
||||
if messages:
|
||||
await Chats.reconcile_messages_by_chat_id(id, user.id, messages)
|
||||
|
||||
return ChatResponse(**chat.model_dump())
|
||||
else:
|
||||
raise HTTPException(
|
||||
|
||||
Reference in New Issue
Block a user