Skip to content

fix(workspace): a chat keeps its fallback title when the generator has nothing to name (#3533) - #3635

Merged
vybe merged 1 commit into
devfrom
feature/3533-title-failure-text
Oct 13, 2026
Merged

vybe merged 1 commit into
devfrom
feature/3533-title-failure-text

Conversation

@obasilakis

@obasilakis obasilakis commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • An opener with no topic ("yo", "Run sleep 40, then say done.") made the title model describe its own inability, and that text was stored as the chat title.
  • Both title prompts now define the reply for "nothing to title": exactly NONE.
  • _is_no_title treats the sentinel and a closed set of failure phrasings as no title. _generate_thread_title returns None, nothing is stored, the derived first-line title stands, and the existing one retry on the next exchange still runs.
  • The outcome is recorded as ok in the generator health record. Three greetings in a row leave the operator alert quiet.

Changes

  • src/backend/client_portal/service.py: NONE rule in _TITLE_PROMPT and _TITLE_PROMPT_OPENER, _NO_TITLE_SENTINEL, _NO_TITLE_RE, _is_no_title, one branch in _generate_thread_title
  • tests/unit/test_3533_title_failure_text.py: new
  • docs/memory/feature-flows/workspace-chat-tabs-and-titles.md: one paragraph

Test Plan

  • cd tests && pytest unit/test_3533_title_failure_text.py unit/test_ent473_chat_titles.py unit/test_ent79_portal_exposure.py: 168 passed. The new file failed 33 of 34 before the fix.
  • Live check of the new opener prompt against the title model, 1 sample per opener, 16 openers:
    • Topicless openers returning NONE: 5 of 5 ("Run sleep 40, then say done.", "yo", "hi", "test", "Do it.")
    • Real requests titled: 10 of 11 ("Fix the deploy script" gave "Deploy script fix needed", "List all open pull requests" gave "Open pull requests overview"). "What's the weather in Athens tomorrow?" returned NONE; that chat keeps its first line as title.
  • Manual: open a Workspace chat with Run sleep 40, then say done.; tab and sidebar show the message's first line.

Known limits

  • A real title that starts with all-caps NONE plus punctuation is dropped; the chat keeps its first line.
  • Failure text cut at 60 characters before the word "title" or "topic" is stored. The sentinel covers the normal path.
  • Chats already titled with failure text are unchanged.

Fixes #3533

🤖 Generated with Claude Code

…s nothing to name (#3533)

An opener with no topic ("yo", "Run sleep 40, then say done.") made the
title model describe its own inability, and that sentence was stored as
the chat title ("Unable to generate title", "Unclear Initial Contact").

Both title prompts now define the reply for "nothing to title": exactly
NONE. `_is_no_title` treats the sentinel and a closed set of failure
phrasings as no title; `_generate_thread_title` then returns None, so
nothing is stored and the derived first-line title stands. The outcome
is recorded as ok, because the generator answered and three greetings in
a row must leave the operator health record quiet. `title_source` stays
unset, so the existing one retry on the next exchange still runs.

Fixes #3533

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@AndriiPasternak31 AndriiPasternak31 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. This fixes #3533 on the path production actually takes (opener-only prompt, reply=""), and the one retry on the next exchange still runs because title_source stays unset.

What I checked:

  • Teeth: with the guard in _generate_thread_title disabled, 5 tests go red on the title assertion itself ('NONE' / 'Unclear Initial Contact' / 'Unable to generate title…' stored, and a write landing). Mutating the sentinel check, the regex, the prompt rule or the health outcome each turns at least one test red.
  • The four strings in the acceptance criteria, the release-test string "Unable to determine topic", and failure text cut at 60 chars are all dropped.
  • Existing title tests (ent473, 2766, 2964, ent79, ent403, 3265, 3114) pass on the PR head and on a merge with current dev. The merge is clean.
  • Nothing outside the background title task changes, and the worst case is the first line as the title, which is what we ship today.

Non-blocking, fine after 1.0:

  1. The open tail on the "unable to … title/topic …" form also drops real titles where the word is the subject, e.g. "Unable to create topic in Kafka" or "Cannot create title page in Word". Harmless (the first line stands), but worth anchoring.
  2. Paraphrases still get through, e.g. "Unable to determine specific topic", "I'm sorry, I can't generate a title", "Topic unclear", lowercase "none - greeting". The NONE rule should make them rare. If they show up, feeding the retry the exchange rather than the second message alone is the sturdier fix.
  3. A NONE answer records ok. Fine for now, but an install whose model says NONE to everything would look healthy. A separate no-topic count would make that visible.
  4. Small: worth adding the release-test case (opener "hellp" → "Unable to determine topic") to the parametrised test. It is caught today.

I haven't re-run the live model check myself; I'm relying on the sample in the PR description for how often the model answers NONE.

@vybe vybe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge-train: batch validated on train/20261012-2333 (#3639)

@vybe
vybe merged commit 1a98c24 into dev Oct 13, 2026
25 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants