Skip to content

fix(agent-mode): correct session tab titles for codex and Claude Code#2607

Merged
logancyang merged 2 commits into
v4-previewfrom
issue-113-agent-session-titles
Jun 14, 2026
Merged

fix(agent-mode): correct session tab titles for codex and Claude Code#2607
logancyang merged 2 commits into
v4-previewfrom
issue-113-agent-session-titles

Conversation

@logancyang

Copy link
Copy Markdown
Owner

Summary

Fixes the Agent Mode tab-title bug (P0): codex tabs showed the raw injected <copilot-context> envelope and Claude Code tabs showed the backend name "Claude" instead of a conversation title. opencode was already correct.

Closes logancyang/obsidian-copilot-preview#113

Root cause

Session titles were entirely backend-provided. Only opencode runs a title-summarizer agent, so only it returned clean titles. codex names a session after the first prompt it receives (which leads with our context envelope when notes are attached), and the Claude SDK exposes no title API at all.

Change

  • Add a required summarizesSessionTitle: boolean to BackendDescriptor (opencode true; codex / Claude Code false).
  • Backends that summarize keep trusting their session/list and pushed session_info_update titles.
  • Backends that don't summarize now derive the tab label client-side from the user's first visible message, reusing the existing deriveChatTitleFromMessages helper (strips wikilinks, truncates), and ignore any backend-provided title (pollSessionTitle and the session_info_update handler are gated).
  • The derived title is recorded agent-sourced, so a user Rename still wins and the first message's title stays stable across later turns.

A single backendSummarizesTitle() helper centralizes the check; it defaults to true when no descriptor is wired (legacy/test construction) so existing opencode-path tests are unaffected.

Tests

  • New AgentSession client-derived title (non-summarizing backends) suite: codex/Claude derive from the first message, wikilink stripping, first-message stability across turns, user-rename precedence, opencode does not derive, pushed/polled titles ignored for non-summarizing backends.
  • All 1007 agent-mode tests pass; tsc and eslint clean.

Notes

  • Preview-phase scope: this fixes titles going forward. Pre-existing sessions that already stored a bad codex title keep it (no migration), consistent with preview-phase policy.

🤖 Generated with Claude Code

codex named sessions after the raw first prompt, leaking the injected
<copilot-context> envelope into the tab title, and Claude Code fell back to the
backend display name ("Claude") because its SDK exposes no title API. Only
opencode summarizes its own titles.

Add a required `summarizesSessionTitle` flag to BackendDescriptor (opencode:
true, codex/claude: false). Backends that summarize keep trusting their
session/list and pushed session_info_update titles; the rest now derive the tab
label client-side from the user's first visible message (reusing
deriveChatTitleFromMessages) and ignore backend-provided titles. The derived
title is agent-sourced, so a user Rename still wins and the first message's
title is stable across later turns.

Closes logancyang/obsidian-copilot-preview#113

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88895298fd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agentMode/backends/codex/descriptor.ts
Address Codex review: sweepNativeSessions() merged listSessions titles into the
recent-chats index for every backend, so a codex session whose first prompt
carried attached context could still be discovered (and reopened) with the raw
<copilot-context> title, bypassing the AgentSession-level gating.

Gate the sweep on summarizesSessionTitle too: non-summarizing backends (codex,
Claude Code) are skipped entirely since the sweep has no transcript to derive a
clean title from. Their sessions are still indexed via flushIndexTouch, which
uses the client-derived title.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@logancyang logancyang merged commit e1abb92 into v4-preview Jun 14, 2026
2 checks passed
@logancyang logancyang deleted the issue-113-agent-session-titles branch June 14, 2026 03:45
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.

1 participant