Skip to content

feat(examples-chat): derive thread titles from first user message#242

Merged
blove merged 1 commit into
mainfrom
claude/nav-v2-backend-titles
May 11, 2026
Merged

feat(examples-chat): derive thread titles from first user message#242
blove merged 1 commit into
mainfrom
claude/nav-v2-backend-titles

Conversation

@blove
Copy link
Copy Markdown
Contributor

@blove blove commented May 11, 2026

Summary

  • Adds _maybe_write_thread_title to the Python graph. On the first user message in a thread, writes a derived 50-char title into thread metadata via the LangGraph SDK.
  • Idempotent (only writes when metadata.title is absent). Error-swallowing — title is a UX nicety, never a blocker.

Pairs with PR #241 (lib primitives) and the upcoming PR 3 (demo wiring) for the nav v2 design.

Test plan

  • pytest tests/test_graph_smoke.py::TestSliceTitle green (6 tests)
  • Full pytest tests/ green (existing smokes still pass — 18 total)
  • Live smoke: send first message in a fresh thread → /threads/search returns the title on next refresh

🤖 Generated with Claude Code

Adds a _maybe_write_thread_title side effect to the generate node:
on the first user message in a thread (metadata.title absent), the
node writes a 50-char slice into LangGraph thread metadata via the
official SDK client. Idempotent and error-swallowing so titles
never block a run.

The threads.service.ts in the demo already prefers metadata.title
over the truncated-id fallback, so threads now render with real
labels in the drawer after one round-trip per thread.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cacheplane Ready Ready Preview, Comment May 11, 2026 4:32pm

Request Review

@blove blove merged commit c36f361 into main May 11, 2026
14 checks passed
@blove blove deleted the claude/nav-v2-backend-titles branch May 11, 2026 16:39
blove added a commit that referenced this pull request May 11, 2026
…ers (#243)

* feat(chat): mount chat-timeline-slider inside chat-debug

Demotes the slider from a primary nav surface to an advanced
affordance inside the Debug overlay. The two UX patterns —
inline gutter markers (new) + panel slider (legacy) — now ship
side-by-side as a library-consumer reference.

* refactor(examples-chat): remove Phase 6/7 fixed side panels

Drops the timeline-panel and threads-panel side panels along
with their palette toggles, persistence keys, and responsive
overrides from PR #240. The replacement threads-drawer + inline
checkpoint markers land in the next commit. The legacy timeline
slider is still reachable via the Debug overlay.

* feat(examples-chat): nav v2 — header + threads drawer + inline checkpoint markers

Replaces the Phase 6/7 fixed side panels (removed in the previous
commit) with a left-edge slide-out threads drawer toggled from a
permanent hamburger top-left, plus inline checkpoint markers in
each assistant turn's gutter.

Drawer uses push mode at >=1024px (chat main reflows via
padding-left) and overlay-with-scrim below. agent.messageCheckpoints()
from the LangGraph adapter pairs each AIMessage id with its newest
containing checkpoint; chat-message [checkpointId] picks up the
right id and bubbles Rewind/Fork up to the existing
onTimelineReplay / onTimelineFork handlers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(chat,examples-chat): forward replay/fork outputs through chat-popup + chat-sidebar

Completes cross-mode wiring for the nav v2 redesign. Both
wrapper compositions (chat-popup, chat-sidebar) now expose
replayRequested + forkRequested outputs that forward from
their internal <chat> instance, and the demo-shell's popup
and sidebar mode routes bind those outputs to the same
onTimelineReplay / onTimelineFork handlers /embed uses.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* fix(examples-chat): refresh threads list after run completes

The backend writes metadata.title on the first user message via
_maybe_write_thread_title (PR #242). Without this refresh, the
drawer keeps showing 'Thread <id-slice>' for the active thread
until the user manually switches threads. New effect listens for
status transitioning out of 'running' and re-fetches the threads
list so the title lands in the drawer as soon as the run ends.

* chore: regenerate api-docs for nav v2 demo wiring

* fix(examples-chat,chat): drawer + layout fixes from live smoke

Three issues uncovered by live smoke against the dev server:

1. Drawer animation: the `[data-open] transform: translateX(0)`
   CSS rule unreliable across HMR + change detection — switch the
   chat-thread-drawer composition to a direct `[style.left.px]`
   binding (0 when open, -320 when closed) with `transition: left
   200ms ease`. Drops the CSS attribute selector approach.

2. Redundant header: the demo-shell wrapped both the hamburger
   and the existing floating-fixed `<app-control-palette>` in a
   new top header strip, which double-anchored the palette and
   visually crowded the top. Drop the header; pin the hamburger
   as its own fixed top-left floating button so the palette keeps
   its original top-right floating-corner placement.

3. Hamburger sizing: scaled up the default size (32 → 36) to
   match the palette's visual weight and added a subtle drop
   shadow so it reads as a floating control like the palette.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
blove added a commit that referenced this pull request May 12, 2026
…rk (#271)

Brings the canonical smoke checklist current with 29 PRs that landed
between Phase 7 (#239) and today without checklist updates. Specifically:

Updated sections:
- chat-debug devtools — replaced bottom-drawer model with floating
  launcher + status pill + switch (PRs #249, #251)
- Control palette — palette v2 (status pill, shadcn-styled panel, PR #244)
- Generative UI / A2UI surfaces — single-bubble invariant (PR #255),
  parent-emits-envelopes architecture (PR #259), wrapped-content +
  tool_calls coexistence (PR #255), envelope reorder
- Server-side wire format — tool_calls preserved on the final AI
- Replaced 'Multi-thread' section with 'Sidenav (thread management)'
  reflecting the permanent semantic <nav> + Active/Archived sections
  (PR #253) and removing the old palette-toggled drawer model

Added sections:
- Cmd+K history search — palette open/search/select/close, archived
  result subtitle, keyboard navigation (PR #253)
- Per-row thread actions — kebab menu order per state (active, pinned,
  archived), rename + pin/unpin + archive/unarchive + delete flows
  (PRs #258, #260, #267)
- Thread titles — first-user-message derivation, idempotent writes,
  manual rename precedence (PR #242)
- Progressive A2UI streaming — per-component fallback transition
  observable during streaming window (PRs #252, #261, #262, #268, #269)
- Inline checkpoint markers — render between messages during multi-step
  runs (PR #243)
- Responsive sidenav — viewport breakpoints, auto-collapse behavior (PR #240)

Total: ~58 new check items across 6 new sections, plus rewrites to 5
existing sections. Original 333-line checklist → 391 lines / 237 check
items.
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