Summary
Session titles are currently generated once from the first user message and never updated, even as the conversation evolves significantly. This ticket wires a title refresh into the existing TokenAwareSummarizingMemory summarization cycle so the title stays meaningful over long, topic-drifting conversations — with no additional AI calls.
Motivation
A conversation that starts as "How do I center a div?" and evolves into a deep Kotlin coroutines debugging session still shows the original title in the sidebar. This makes it hard for users to find past conversations and gives no signal that the session has changed direction.
Proposed approach
Piggyback on the existing summarizeAndPrune() cycle in TokenAwareSummarizingMemory. When a new SessionConversationSummary is produced, derive a refreshed title from the summary data already available — no extra AI call needed.
Title derivation logic (in priority order):
- Use
recentContext (first sentence, truncated to ~60 chars) if it's meaningfully different from the current title
- Fall back to
mainTopics.take(2).joinToString(" · ") if recentContext is blank
- If neither yields anything useful, keep the existing title unchanged
Change detection — only update if:
- The new candidate title differs from the current title by more than a trivial threshold (e.g. Levenshtein distance > 20% of current title length), to avoid flickering on minor rewordings
- The session has at least
MIN_MESSAGES_FOR_TITLE_REFRESH messages (e.g. 10) so very short sessions are not affected
Implementation
-
TokenAwareSummarizingMemory — after mergeWithExistingSummary() produces a new summary, invoke an optional onTitleSuggested: ((String) -> Unit)? callback with the derived title candidate. Caller decides whether to apply it.
-
SessionManager (or wherever TokenAwareSummarizingMemory is constructed) — wire onTitleSuggested to call chatSessionService.updateSessionTitle(sessionId, newTitle) when the candidate passes the change-detection check.
-
ChatState / ChatViewModel — emit the updated title so ChatView reflects it live in the header without a full reload.
-
Guard — skip title refresh if:
- The user has manually renamed the session (track a
userHasRenamedSession flag on the session)
- The session has fewer than
MIN_MESSAGES_FOR_TITLE_REFRESH messages
- Summarization is running in fallback (basic) mode — basic summaries are not rich enough for a reliable title
Summary
Session titles are currently generated once from the first user message and never updated, even as the conversation evolves significantly. This ticket wires a title refresh into the existing
TokenAwareSummarizingMemorysummarization cycle so the title stays meaningful over long, topic-drifting conversations — with no additional AI calls.Motivation
A conversation that starts as "How do I center a div?" and evolves into a deep Kotlin coroutines debugging session still shows the original title in the sidebar. This makes it hard for users to find past conversations and gives no signal that the session has changed direction.
Proposed approach
Piggyback on the existing
summarizeAndPrune()cycle inTokenAwareSummarizingMemory. When a newSessionConversationSummaryis produced, derive a refreshed title from the summary data already available — no extra AI call needed.Title derivation logic (in priority order):
recentContext(first sentence, truncated to ~60 chars) if it's meaningfully different from the current titlemainTopics.take(2).joinToString(" · ")ifrecentContextis blankChange detection — only update if:
MIN_MESSAGES_FOR_TITLE_REFRESHmessages (e.g. 10) so very short sessions are not affectedImplementation
TokenAwareSummarizingMemory— aftermergeWithExistingSummary()produces a new summary, invoke an optionalonTitleSuggested: ((String) -> Unit)?callback with the derived title candidate. Caller decides whether to apply it.SessionManager(or whereverTokenAwareSummarizingMemoryis constructed) — wireonTitleSuggestedto callchatSessionService.updateSessionTitle(sessionId, newTitle)when the candidate passes the change-detection check.ChatState/ChatViewModel— emit the updated title soChatViewreflects it live in the header without a full reload.Guard — skip title refresh if:
userHasRenamedSessionflag on the session)MIN_MESSAGES_FOR_TITLE_REFRESHmessages