fix(title): strip markdown labels and skip empty placeholders in auto-title (#611)
Squash-merges PR #611 (@franksong2702). Fixes two edge cases in auto-generated session titles. 1. Strip Markdown labels (`**Session Title:**`, `Title:`) from sanitizer output — these were being persisted verbatim when the LLM emitted them. 2. Skip empty assistant tool-call placeholder messages when extracting the first exchange for title generation — previously the empty row could be latched onto instead of the first real answer. Also tightens the title prompt to explicitly forbid Markdown, bullets, and label prefixes. 1371 tests passing, QA harness green. Co-authored-by: Frank Song <franksong2702@gmail.com>
This commit is contained in:
@@ -76,8 +76,14 @@ def _strip_thinking_markup(text: str) -> str:
|
||||
def _sanitize_generated_title(text: str) -> str:
|
||||
"""Sanitize LLM-generated title text before persisting to session."""
|
||||
s = _strip_thinking_markup(text or '')
|
||||
s = re.sub(
|
||||
r'^\s*(?:[*_`~]+\s*)?(?:session\s+title|title)\s*[::]\s*(?:[*_`~]+\s*)?',
|
||||
'',
|
||||
s,
|
||||
flags=re.IGNORECASE,
|
||||
)
|
||||
s = re.sub(r'^\s*title\s*:\s*', '', s, flags=re.IGNORECASE)
|
||||
s = s.strip(" \t\r\n\"'`")
|
||||
s = s.strip(" \t\r\n\"'`*_~")
|
||||
s = re.sub(r'\s+', ' ', s).strip()
|
||||
# Guard against chain-of-thought leakage and meta-reasoning patterns.
|
||||
if _looks_invalid_generated_title(s):
|
||||
@@ -128,7 +134,9 @@ def _first_exchange_snippets(messages):
|
||||
if role == 'user' and not user_text:
|
||||
user_text = _message_text(m.get('content'))
|
||||
elif role == 'assistant' and not asst_text:
|
||||
asst_text = _message_text(m.get('content'))
|
||||
candidate = _message_text(m.get('content'))
|
||||
if candidate:
|
||||
asst_text = candidate
|
||||
if user_text and asst_text:
|
||||
break
|
||||
return user_text[:500], asst_text[:500]
|
||||
@@ -149,6 +157,7 @@ def _title_prompts(user_text: str, assistant_text: str) -> tuple[str, list[str]]
|
||||
"Generate a short session title from this conversation start.\n"
|
||||
"Use BOTH the user's question and the assistant's visible answer.\n"
|
||||
"Return only the title text, 3-8 words, as a topic label.\n"
|
||||
"Do not use markdown, bullets, labels, or prefixes like Session Title:.\n"
|
||||
"Do not output a full sentence.\n"
|
||||
"Do not output acknowledgements or completion phrases like OK, done, all set, 测试完成.\n"
|
||||
"Do not describe internal reasoning.\n"
|
||||
@@ -159,6 +168,7 @@ def _title_prompts(user_text: str, assistant_text: str) -> tuple[str, list[str]]
|
||||
"Rewrite this conversation start as a concise noun-phrase title.\n"
|
||||
"Use the actual topic, not the task outcome.\n"
|
||||
"Return title text only.\n"
|
||||
"Do not use markdown, bullets, labels, or prefixes like Session Title:.\n"
|
||||
"Never output acknowledgements, completion status, or meta commentary."
|
||||
),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user