@@ -432,6 +432,14 @@ async def update_chat_by_id(self, id: str, chat: dict, db: AsyncSession | None =
432432 try :
433433 async with get_async_db_context (db ) as db :
434434 chat_item = await db .get (Chat , id )
435+ if chat_item is None :
436+ return None
437+
438+ # Snapshot for the post-commit row diff.
439+ prior_messages = (
440+ (chat_item .chat or {}).get ('history' , {}).get ('messages' , {}) or {}
441+ )
442+
435443 chat = self ._normalize_assistant_content_from_output (chat , chat_item .chat )
436444 chat_item .chat = self ._clean_null_bytes (chat )
437445 chat_item .title = self ._clean_null_bytes (chat ['title' ]) if 'title' in chat else 'New Chat'
@@ -440,6 +448,36 @@ async def update_chat_by_id(self, id: str, chat: dict, db: AsyncSession | None =
440448
441449 await db .commit ()
442450
451+ # Reconcile chat_message rows with the just-written blob.
452+ try :
453+ new_messages = (chat .get ('history' , {}) or {}).get ('messages' , {}) or {}
454+
455+ for message_id , message in new_messages .items ():
456+ if (
457+ isinstance (message , dict )
458+ and message .get ('role' )
459+ and prior_messages .get (message_id ) != message
460+ ):
461+ await ChatMessages .upsert_message (
462+ message_id = message_id ,
463+ chat_id = id ,
464+ user_id = chat_item .user_id ,
465+ data = message ,
466+ db = db ,
467+ )
468+
469+ removed_message_ids = set (prior_messages .keys ()) - set (new_messages .keys ())
470+ if removed_message_ids :
471+ composite_ids = {f'{ id } -{ mid } ' for mid in removed_message_ids }
472+ await db .execute (
473+ delete (ChatMessage )
474+ .where (ChatMessage .chat_id == id )
475+ .where (ChatMessage .id .in_ (composite_ids ))
476+ )
477+ await db .commit ()
478+ except Exception as e :
479+ log .warning (f'Failed to sync chat_message rows: { e } ' )
480+
443481 return ChatModel .model_validate (chat_item )
444482 except Exception :
445483 return None
0 commit comments