From 4e4dbb8783f951a371e2703afba135b97c5122f5 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Mon, 13 Apr 2026 17:15:39 -0400 Subject: [PATCH] fix(chat): feed title model raw turns instead of post-build_context messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _generate_title was receiving the full messages list from build_context, which prepends RAG snippets, RSS excerpts, URL content, and briefing article dumps INTO the user-role message string. The role=="user" filter inside _generate_title then handed that composite blob (capped at 300 chars) to gemma3:4b as "the user's message", so the background model was titling conversations based on article excerpts instead of what the user actually typed — producing wildly wrong titles like "Briefing Profile Preferences & Schedule" for a plain calendar query. See #109. Pass the raw history + user_content + assistant reply instead. Co-Authored-By: Claude Opus 4.6 --- src/fabledassistant/services/generation_task.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/fabledassistant/services/generation_task.py b/src/fabledassistant/services/generation_task.py index 7d60407..a74bd76 100644 --- a/src/fabledassistant/services/generation_task.py +++ b/src/fabledassistant/services/generation_task.py @@ -527,9 +527,22 @@ async def run_generation( should_gen_title = not conv_title or (msg_count > 0 and msg_count % 10 == 0) if should_gen_title: - title_messages = messages + [ - {"role": "assistant", "content": buf.content_so_far} + # Feed the title model the *raw* conversation turns only — never + # the post-build_context ``messages`` list. ``build_context`` + # prepends RAG snippets, RSS excerpts, URL content, and briefing + # article dumps INTO the user message string itself, so filtering + # by role="user" downstream still surfaces that noise as the + # "user's message". That pollution caused wildly-wrong titles + # (bug #109) — the small background model was staring at article + # excerpts instead of what the user actually typed. Pass the + # original history + the raw user_content + the assistant reply. + title_messages: list[dict] = [ + {"role": m["role"], "content": m.get("content") or ""} + for m in history + if m.get("role") in ("user", "assistant") ] + title_messages.append({"role": "user", "content": user_content}) + title_messages.append({"role": "assistant", "content": buf.content_so_far}) async def _bg_title() -> None: try: