[Superseded by #1057] Generate conversation titles with a secondary model - #1056
[Superseded by #1057] Generate conversation titles with a secondary model#1056PeterDaveHello wants to merge 11 commits into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds an opt-in, OpenAI-compatible secondary model flow to automatically generate semantic conversation titles from the first completed exchange, while introducing safer session-title storage semantics and a stable timestamp-based “untitled” display fallback.
Changes:
- Introduces
session-titleutilities for prompt shaping, response sanitization, grapheme-safe truncation, and timestamp display fallbacks. - Adds per-session title-generation state (claim/complete/fail) with serialized storage mutations and stale-request recovery.
- Adds popup settings + storage-backed hook to select/enable a dedicated “conversation title model”, and wires auto-generation into the Independent Panel.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/services/session-title.test.mjs | Unit tests for title message building, sanitization, truncation, timestamp fallback, and request shaping. |
| tests/unit/services/local-session-title.test.mjs | Concurrency/race tests for session updates vs title-generation state updates. |
| tests/unit/services/init-session-title.test.mjs | Tests default/init behavior for new session title-generation metadata fields. |
| tests/unit/hooks/conversation-title-config.test.mjs | Tests default config + persistence behavior (including stripping copied API keys). |
| src/services/session-title.mjs | Implements title-generation request construction, response extraction/sanitization, and fallback display naming. |
| src/services/local-session.mjs | Adds serialized session mutations + title-generation claim/complete/fail APIs and preserves stored title state on stale writes. |
| src/services/init-session.mjs | Extends session schema to include title source and title-generation metadata. |
| src/services/conversation-title-model.mjs | Adds availability check for the configured title model/provider (chat-only). |
| src/popup/sections/FeaturePages.jsx | Adds UI controls to enable auto title generation and select a dedicated title model. |
| src/pages/IndependentPanel/App.jsx | Wires title-generation lifecycle into session updates and displays fallback session names. |
| src/hooks/use-conversation-title-config.mjs | Implements persisted storage + reactive hook for title-generation settings. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Important
Two things to address before merge: a transient title-generation failure permanently strands the conversation without a title (the new failed state is terminal and never retried), and the new settings strings bypass the localization pipeline — no keys were added to src/_locales/en/main.json or any other locale.
Reviewed changes
- Title configuration hook —
use-conversation-title-config.mjspersistsautoGenerateConversationTitle+conversationTitleApiModeinstorage.local, normalizes the api mode viacanonicalizeApiMode, and strips any copiedapiKeybefore saving so the runtime always re-resolves credentials fromconfig.providerSecrets. - Title generation on first exchange —
IndependentPanel/App.jsxstarts a single non-streaming title request once a conversation has exactly one completed exchange, guarded by an in-flightSet, a serializedclaim/complete/failprotocol with generation IDs, stale-pending recovery, and delete/race guards. - Popup settings —
FeaturePages.jsxadds a checkbox + model selector limited to enabled OpenAI-compatible chat endpoints (native Anthropic/Azure/web modes don't resolve throughresolveOpenAICompatibleRequest, so they are excluded as stated). - Prompt, sanitizer, request —
session-title.mjsbuilds a system+user transcript with grapheme-safe head/tail truncation, sanitizes the reply (reasoning blocks, code fences, labels), caps output at 64 tokens with a 15s timeout, and provides a stableYYYY-MM-DD HH:mmfallback display name for untitled sessions. - Session write safety —
local-session.mjs/init-session.mjsserialize mutations, preserve managed title state across stale conversation writes, and default new sessions to untitled (sessionName: null). - Tests — unit tests for the config hook, session metadata, the claim/complete/fail state machine, and prompt/request/sanitize behavior (20 tests, all passing locally).
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Superseded by #1057, which rebuilds the implementation from a clean branch and carries forward the relevant review feedback.
Original summary
YYYY-MM-DD HH:mmtimestamp.Refs #481 and #228.