@@ -127,30 +127,67 @@ class ChatTitleIdResponse(BaseModel):
127127
128128
129129class ChatTable :
130+ def _clean_null_bytes (self , obj ):
131+ """
132+ Recursively remove actual null bytes (\x00 ) and unicode escape \\ u0000
133+ from strings inside dict/list structures.
134+ Safe for JSON objects.
135+ """
136+ if isinstance (obj , str ):
137+ return obj .replace ("\x00 " , "" ).replace ("\u0000 " , "" )
138+ elif isinstance (obj , dict ):
139+ return {k : self ._clean_null_bytes (v ) for k , v in obj .items ()}
140+ elif isinstance (obj , list ):
141+ return [self ._clean_null_bytes (v ) for v in obj ]
142+ return obj
143+
144+ def _sanitize_chat_row (self , chat_item ):
145+ """
146+ Clean a Chat SQLAlchemy model's title + chat JSON,
147+ and return True if anything changed.
148+ """
149+ changed = False
150+
151+ # Clean title
152+ if chat_item .title :
153+ cleaned = self ._clean_null_bytes (chat_item .title )
154+ if cleaned != chat_item .title :
155+ chat_item .title = cleaned
156+ changed = True
157+
158+ # Clean JSON
159+ if chat_item .chat :
160+ cleaned = self ._clean_null_bytes (chat_item .chat )
161+ if cleaned != chat_item .chat :
162+ chat_item .chat = cleaned
163+ changed = True
164+
165+ return changed
166+
130167 def insert_new_chat (self , user_id : str , form_data : ChatForm ) -> Optional [ChatModel ]:
131168 with get_db () as db :
132169 id = str (uuid .uuid4 ())
133170 chat = ChatModel (
134171 ** {
135172 "id" : id ,
136173 "user_id" : user_id ,
137- "title" : (
174+ "title" : self . _clean_null_bytes (
138175 form_data .chat ["title" ]
139176 if "title" in form_data .chat
140177 else "New Chat"
141178 ),
142- "chat" : form_data .chat ,
179+ "chat" : self . _clean_null_bytes ( form_data .chat ) ,
143180 "folder_id" : form_data .folder_id ,
144181 "created_at" : int (time .time ()),
145182 "updated_at" : int (time .time ()),
146183 }
147184 )
148185
149- result = Chat (** chat .model_dump ())
150- db .add (result )
186+ chat_item = Chat (** chat .model_dump ())
187+ db .add (chat_item )
151188 db .commit ()
152- db .refresh (result )
153- return ChatModel .model_validate (result ) if result else None
189+ db .refresh (chat_item )
190+ return ChatModel .model_validate (chat_item ) if chat_item else None
154191
155192 def _chat_import_form_to_chat_model (
156193 self , user_id : str , form_data : ChatImportForm
@@ -160,10 +197,10 @@ def _chat_import_form_to_chat_model(
160197 ** {
161198 "id" : id ,
162199 "user_id" : user_id ,
163- "title" : (
200+ "title" : self . _clean_null_bytes (
164201 form_data .chat ["title" ] if "title" in form_data .chat else "New Chat"
165202 ),
166- "chat" : form_data .chat ,
203+ "chat" : self . _clean_null_bytes ( form_data .chat ) ,
167204 "meta" : form_data .meta ,
168205 "pinned" : form_data .pinned ,
169206 "folder_id" : form_data .folder_id ,
@@ -195,9 +232,15 @@ def update_chat_by_id(self, id: str, chat: dict) -> Optional[ChatModel]:
195232 try :
196233 with get_db () as db :
197234 chat_item = db .get (Chat , id )
198- chat_item .chat = chat
199- chat_item .title = chat ["title" ] if "title" in chat else "New Chat"
235+ chat_item .chat = self ._clean_null_bytes (chat )
236+ chat_item .title = (
237+ self ._clean_null_bytes (chat ["title" ])
238+ if "title" in chat
239+ else "New Chat"
240+ )
241+
200242 chat_item .updated_at = int (time .time ())
243+
201244 db .commit ()
202245 db .refresh (chat_item )
203246
@@ -588,8 +631,15 @@ def get_chat_list_by_chat_ids(
588631 def get_chat_by_id (self , id : str ) -> Optional [ChatModel ]:
589632 try :
590633 with get_db () as db :
591- chat = db .get (Chat , id )
592- return ChatModel .model_validate (chat )
634+ chat_item = db .get (Chat , id )
635+ if chat_item is None :
636+ return None
637+
638+ if self ._sanitize_chat_row (chat_item ):
639+ db .commit ()
640+ db .refresh (chat_item )
641+
642+ return ChatModel .model_validate (chat_item )
593643 except Exception :
594644 return None
595645
0 commit comments