From f679c61da1c679be4e1d5730dceea42d1870031c Mon Sep 17 00:00:00 2001 From: gdeyoung Date: Thu, 2 Jul 2026 20:34:26 -0500 Subject: [PATCH] fix: sanitize JSON responses in automatic chat renaming When utility model returns JSON instead of plain text (common with small models like Gemma 4B), extract headline field, fall back to first user message, then default to Conversation. Addresses symptom of #1750 --- .../python/monologue_start/_60_rename_chat.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/extensions/python/monologue_start/_60_rename_chat.py b/extensions/python/monologue_start/_60_rename_chat.py index ee2361cf65..1381ff040c 100644 --- a/extensions/python/monologue_start/_60_rename_chat.py +++ b/extensions/python/monologue_start/_60_rename_chat.py @@ -53,6 +53,42 @@ async def change_name(self): # update name if new_name: new_name = " ".join(str(new_name).split()) + # P028: Guard against JSON-looking names (utility model echoes) + stripped = new_name.lstrip() + if stripped and stripped[0] in "{[": + import json as _json + extracted = None + # Step 1: Try to parse JSON and extract headline (best quality) + try: + parsed = _json.loads(stripped) + headline = parsed.get("headline") + if isinstance(headline, str) and headline.strip(): + extracted = headline.strip() + else: + thoughts = parsed.get("thoughts") + if isinstance(thoughts, list) and thoughts: + first = thoughts[0] + if isinstance(first, str) and first.strip(): + extracted = first.strip() + except (_json.JSONDecodeError, ValueError, AttributeError): + pass + # Step 2: Fall back to first user message topic + if not extracted: + try: + msgs = self.agent.history.output() + for msg in msgs: + if not msg.ai and msg.content: + content = str(msg.content) + first_line = content.split(chr(10))[0].split(".")[0].strip() + if first_line: + extracted = first_line[:40] + if len(first_line) > 40: + extracted += "..." + break + except Exception: + pass + # Step 3: Last resort + new_name = extracted or "Conversation" if len(new_name) > 40: new_name = new_name[:40] + "..." if not new_name: