Problem
Sessions start as untitled (/name shows a suggestion only on demand). Users must manually run /name to set a title. Multi-topic sessions keep their original title even after shifting topics entirely. Meanwhile, an LLM slug generator already exists in the codebase (llm-slug-generator) for memory filenames — it just isnt wired into session titling.
Related: #77165 (basic auto-title request), #94529 (auto-derive in sidebar), #81781 (improve derived titles beyond first message)
Proposal: Three-Phase Auto-Titling
Phase 1 — Lazy Initial Title (after N messages, not immediately)
Dont title on session creation or first message. Wait until N messages have passed (configurable, default 4-6). This avoids titles like "hi" or "help" from one-word openers, and gives enough context for a meaningful slug.
sessions:
autoTitle:
enabled: true
triggerAfterMessages: 5 # wait for 5th message before first title gen
model: "openai/gpt-4.1-mini" # cheap model override, falls back to default
Phase 2 — Cheap Model for Title Generation
Title generation does NOT need a frontier model. A cheap, fast model works perfectly:
| Model |
Cost per gen |
Latency |
gpt-4.1-mini |
~$0.00015 |
~300ms |
claude-haiku-4.5 |
~$0.00030 |
~400ms |
deepseek-v3 |
~$0.00005 |
~500ms |
| Provider default |
varies |
varies |
Config should allow a dedicated titleModel override separate from the session model, defaulting to the cheapest available provider model. Title prompts are tiny (~200 tokens input, ~10 tokens output) so cost is negligible even with frontier models, but the principle of using cheap models for cheap tasks matters.
Phase 3 — Periodic Topic-Aware Re-Titling
Sessions drift. A conversation that starts as "skill audit" might shift to "LinkedIn content strategy" after 30 messages. The title should track the active topic.
sessions:
autoTitle:
reTitleInterval: 20 # re-evaluate title every N messages
reTitleWindow: 15 # use last N messages for context (sliding window)
reTitleMinChange: true # only rename if topic meaningfully changed
Implementation:
- Every
reTitleInterval messages, feed the last reTitleWindow messages to the title model
- Compare generated title against current title (simple string similarity or LLM-based "did the topic change?")
- Only apply rename if the new title is meaningfully different (avoid flickering)
- Titles should be 2-4 word lowercase slugs:
"skill-audit-cleanup", "linkedin-automation", "session-naming-proposal"
Reuse Existing Infrastructure
The llm-slug-generator already exists in dist/ and handles:
- Short 1-2 word lowercase hyphenated slugs
- LLM-based generation from conversation content
- Memory filename integration
Wire this same generator (or a configurable variant) into session title mutation on the trigger conditions above.
UX Behavior
- Title appears in sidebar,
/sessions list, Control UI tabs, and session history
/name with no args shows current title + when it was last auto-generated
- Manual
/name <title> overrides and locks the title (no more auto-renames for that session)
/name --auto re-enables auto-titling for a manually-named session
Configuration Surface
sessions:
autoTitle:
enabled: false # default off, opt-in
triggerAfterMessages: 5 # messages before first title gen (min 3)
model: null # null = cheapest available provider model
reTitle:
enabled: true # periodic re-titling
interval: 20 # messages between re-evaluations
window: 15 # last N messages used as context
minDistance: 0.4 # string similarity threshold (0-1) to skip no-op renames
Edge Cases
- Single-message sessions: never titled (below
triggerAfterMessages)
- Very short sessions: titled at message N, then session ends — perfectly fine
- Rapid-fire messages: debounce title generation; dont fire on every message in a burst
- Subagent sessions: auto-title based on task description (available immediately, no N-message wait needed)
- Channel-bound sessions: may want different auto-title behavior (group chats vs DMs)
Precedents
- ChatGPT: auto-titles after ~2-3 exchanges
- Claude: auto-titles immediately from first prompt
- Cursor: auto-titles chat sessions
- All of them occasionally produce dumb titles from insufficient context — the
triggerAfterMessages approach directly addresses this known failure mode
Scope
This is a gateway-side feature: the model call, title storage, and trigger logic all live in the gateway. The Control UI and TUI already consume and display session labels — no UI changes required beyond the existing #94529 and #89922 work.
Migration
Backward-compatible. Default is enabled: false. Existing /name behavior unchanged. Sessions with manually-set titles are not auto-renamed.
Problem
Sessions start as untitled (
/nameshows a suggestion only on demand). Users must manually run/nameto set a title. Multi-topic sessions keep their original title even after shifting topics entirely. Meanwhile, an LLM slug generator already exists in the codebase (llm-slug-generator) for memory filenames — it just isnt wired into session titling.Related: #77165 (basic auto-title request), #94529 (auto-derive in sidebar), #81781 (improve derived titles beyond first message)
Proposal: Three-Phase Auto-Titling
Phase 1 — Lazy Initial Title (after N messages, not immediately)
Dont title on session creation or first message. Wait until
Nmessages have passed (configurable, default 4-6). This avoids titles like "hi" or "help" from one-word openers, and gives enough context for a meaningful slug.Phase 2 — Cheap Model for Title Generation
Title generation does NOT need a frontier model. A cheap, fast model works perfectly:
gpt-4.1-miniclaude-haiku-4.5deepseek-v3Config should allow a dedicated
titleModeloverride separate from the session model, defaulting to the cheapest available provider model. Title prompts are tiny (~200 tokens input, ~10 tokens output) so cost is negligible even with frontier models, but the principle of using cheap models for cheap tasks matters.Phase 3 — Periodic Topic-Aware Re-Titling
Sessions drift. A conversation that starts as "skill audit" might shift to "LinkedIn content strategy" after 30 messages. The title should track the active topic.
Implementation:
reTitleIntervalmessages, feed the lastreTitleWindowmessages to the title model"skill-audit-cleanup","linkedin-automation","session-naming-proposal"Reuse Existing Infrastructure
The
llm-slug-generatoralready exists indist/and handles:Wire this same generator (or a configurable variant) into session title mutation on the trigger conditions above.
UX Behavior
/sessionslist, Control UI tabs, and session history/namewith no args shows current title + when it was last auto-generated/name <title>overrides and locks the title (no more auto-renames for that session)/name --autore-enables auto-titling for a manually-named sessionConfiguration Surface
Edge Cases
triggerAfterMessages)Precedents
triggerAfterMessagesapproach directly addresses this known failure modeScope
This is a gateway-side feature: the model call, title storage, and trigger logic all live in the gateway. The Control UI and TUI already consume and display session labels — no UI changes required beyond the existing #94529 and #89922 work.
Migration
Backward-compatible. Default is
enabled: false. Existing/namebehavior unchanged. Sessions with manually-set titles are not auto-renamed.