1111from ..models import ConversationInStore , Message
1212from ..utils import g_config
1313from ..utils .singleton import Singleton
14+ import re
1415
16+ def _normalize_content (content : str ) -> str :
17+ """Remove <think>...</think> tags and strip whitespace from content."""
18+ # Remove think tags
19+ cleaned_content = re .sub (r"<think>.*?</think>\n?" , "" , content , flags = re .DOTALL )
20+ # Strip leading/trailing whitespace
21+ return cleaned_content .strip ()
1522
1623def hash_message (message : Message ) -> str :
1724 """Generate a hash for a single message."""
@@ -171,6 +178,23 @@ def get(self, key: str) -> Optional[ConversationInStore]:
171178 logger .error (f"Failed to retrieve messages for key { key } : { e } " )
172179 return None
173180
181+ def clean_assistant_messages (self , messages : List [Message ]) -> List [Message ]:
182+ """Create a new list of messages with assistant content cleaned."""
183+ cleaned_messages = []
184+ for msg in messages :
185+ if msg .role == "assistant" and isinstance (msg .content , str ):
186+ # Create a new Message object with cleaned content
187+ normalized_content = _normalize_content (msg .content )
188+ # Only create a new object if content actually changed
189+ if normalized_content != msg .content :
190+ cleaned_msg = Message (role = msg .role , content = normalized_content , name = msg .name )
191+ cleaned_messages .append (cleaned_msg )
192+ else :
193+ cleaned_messages .append (msg )
194+ else :
195+ cleaned_messages .append (msg )
196+ return cleaned_messages
197+
174198 def find (self , model : str , messages : List [Message ]) -> Optional [ConversationInStore ]:
175199 """
176200 Search conversation data by message list.
@@ -185,16 +209,38 @@ def find(self, model: str, messages: List[Message]) -> Optional[ConversationInSt
185209 if not messages :
186210 return None
187211
212+ # --- Find with raw messages ---
213+ if conv := self ._find_by_message_list (model , messages ):
214+ logger .debug ("Found conversation with raw message history." )
215+ return conv
216+
217+ # --- Find with cleaned messages ---
218+ cleaned_messages = self .clean_assistant_messages (messages )
219+ if conv := self ._find_by_message_list (model , cleaned_messages ):
220+ logger .debug ("Found conversation with cleaned message history." )
221+ return conv
222+
223+ logger .debug ("No conversation found for either raw or cleaned history." )
224+ return None
225+
226+ def _find_by_message_list (
227+ self , model : str , messages : List [Message ]
228+ ) -> Optional [ConversationInStore ]:
229+ """Internal find implementation based on a message list."""
188230 for c in g_config .gemini .clients :
189231 message_hash = hash_conversation (c .id , model , messages )
232+
190233 key = f"{ self .HASH_LOOKUP_PREFIX } { message_hash } "
191234 try :
192235 with self ._get_transaction (write = False ) as txn :
193236 mapped = txn .get (key .encode ("utf-8" ))
194237 if mapped :
238+ logger .debug (f"Found mapped key '{ mapped .decode ('utf-8' )} ' for hash '{ message_hash } '." )
195239 return self .get (mapped .decode ("utf-8" )) # type: ignore
196240 except Exception as e :
197- logger .error (f"Failed to retrieve messages by message list for client { c .id } : { e } " )
241+ logger .error (
242+ f"Failed to retrieve messages by message list for hash { message_hash } and client { c .id } : { e } "
243+ )
198244 continue
199245
200246 if conv := self .get (message_hash ):
0 commit comments