Skip to content

feat(acp): broadcast session title updates to daemon clients - #5032

Closed
qqqys wants to merge 2 commits into
QwenLM:mainfrom
qqqys:feat/session-title-update-notification
Closed

feat(acp): broadcast session title updates to daemon clients#5032
qqqys wants to merge 2 commits into
QwenLM:mainfrom
qqqys:feat/session-title-update-notification

Conversation

@qqqys

@qqqys qqqys commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

When a session title is recorded in the ACP child — auto-generated after a turn (fast-model side query) or set by an in-process /rename — the child now notifies attached daemon clients. The recording service exposes a title-recorded observer; the ACP session registers it and forwards the title over the agent→bridge extNotification side-channel (qwen/notify/session/title-update); the bridge demuxes it into the canonical session_metadata_updated bus event with {sessionId, title, titleSource} — the same envelope manual HTTP renames already publish, so clients keep a single "this session's name changed" signal.

A title update is intentionally NOT sent as an ACP SessionUpdate variant: the external @agentclientprotocol/sdk union would reject an unknown kind at validation. This follows the existing current_model_update extNotification precedent.

Why it's needed

Auto-generated titles land in the child's chat recording — the bridge never sees the write, and listSessions computes titles lazily (customTitle ?? first prompt). Today an HTTP client (e.g. a web UI over qwen serve) can only discover the generated title by re-polling the session list, so sidebars keep showing the raw first-prompt text (or "untitled") until some unrelated action triggers a refresh. With this event, clients refresh the moment the title exists.

Reviewer Test Plan

How to verify

  1. Configure a fastModel in settings so auto-titling is active, start qwen serve, and create a session via POST /session.
  2. Subscribe to GET /session/:id/events and send a first prompt.
  3. A few seconds after the turn completes, the SSE stream receives session_metadata_updated with data: {sessionId, title, titleSource: "auto"}, and the session file contains the matching custom_title record. Without this PR, no event is emitted and only a fresh GET /workspace/:cwd/sessions reveals the title.

Unit coverage: two new tests in packages/acp-bridge/src/bridge.test.ts (rebroadcast happy path; malformed payloads dropped — missing/empty/non-string title, missing sessionId). Full runs: acp-bridge 266 passed, cli Session.test.ts 124 passed, core chatRecordingService.test.ts 25 passed; workspace typecheck clean.

Evidence (Before & After)

Before: first prompt in a fresh daemon session → SSE stream shows only session_update / turn_complete frames; the sidebar of a connected web client keeps the first-prompt placeholder title until its next poll.

After: same flow → SSE stream additionally receives session_metadata_updated {sessionId, title: "<generated 3-7 word title>", titleSource: "auto"} seconds after turn_complete; the connected web client refreshes its session list immediately (verified end-to-end against a web UI driving qwen serve locally).

Tested on

OS Status
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

🤖 Generated with Claude Code

衍星 and others added 2 commits June 12, 2026 16:12
Auto-generated session titles land in the ACP child's chat recording —
the daemon bridge never sees the write, and listSessions computes titles
lazily, so HTTP clients could only discover a new title by re-polling
the session list.

Now chatRecordingService exposes a title-recorded observer; the ACP
session registers it and forwards titles over the agent->bridge
extNotification side-channel (qwen/notify/session/title-update — a title
update is not an ACP SessionUpdate variant, matching the
current_model_update precedent). The bridge demuxes it into the
canonical session_metadata_updated bus event, the same envelope manual
HTTP renames publish, so clients keep ONE "name changed" signal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@qqqys

qqqys commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #5035 with clean commit metadata.

@qqqys qqqys closed this Jun 12, 2026
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