Skip to content

feat(appkit): use chat history in the full chat UI#395

Open
hubertzub-db wants to merge 8 commits into
databricks:mainfrom
hubertzub-db:agent/v2/chatui/4-use-chat-history-in-full-ui
Open

feat(appkit): use chat history in the full chat UI#395
hubertzub-db wants to merge 8 commits into
databricks:mainfrom
hubertzub-db:agent/v2/chatui/4-use-chat-history-in-full-ui

Conversation

@hubertzub-db
Copy link
Copy Markdown

Why

<ChatApp> was a single-conversation shell — no way to revisit a past thread or start a fresh one. The thread-history hooks added in the previous PR were only wired into the build-your-own demo.

What changed

  • <ChatApp> now ships a collapsible history sidebar (history prop, default true; pass false for the old single-conversation layout).
  • Sidebar features: new-chat button, icon-mode collapse, per-thread delete with confirm dialog, date-grouped list (Today / Yesterday / Last 7 / Last 30 / Older).
  • Switching threads re-keys the inner ChatBody so useChat reinitializes with seeded messages — mirrors the manual pattern already used in agent.route.tsx.
  • Sidebar uses inline flow (no position: fixed), so <ChatApp> fits inside a parent below a host header without overlapping it. The dev-playground showcase route was retightened accordingly (h-[calc(100svh-65px)]).
  • Radix popovers (tooltip/dropdown/alert-dialog) are portaled into the chat boundary so they inherit the chat-scoped theme. Open/close animations are disabled for popovers inside that boundary to match the rest of the chat surface.
full-history.mov

Tests

  • Unit tests
  • Tested manually (see above)

Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
@hubertzub-db hubertzub-db requested a review from a team as a code owner May 20, 2026 08:36
@hubertzub-db hubertzub-db requested a review from MarioCadenas May 20, 2026 08:36
- responses-api-transport: normalize CRLF to LF in the SSE line parser
  so the "\n\n" frame-boundary split works behind proxies that re-emit
  events with CRLF line endings. Adds a CRLF-stream unit test.

- use-scroll-to-bottom: switch from useRef + listener-attach-on-mount
  to a state-backed ref callback. The listener-attach effect now
  re-runs when the container DOM node changes, so consumers that
  conditionally render the scroll container (e.g. behind a loading
  gate) still get auto-stick. The public ref type changes from
  RefObject<T | null> to (node: T | null) => void; JSX
  `ref={containerRef}` keeps working because React accepts both
  shapes, and no consumer reads `.current` (verified across the repo).

Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
Follow-up to the parent fix that switched `useScrollToBottom` from
`useRef` to a state-backed ref callback. `ChatMessages` previously
typed `containerRef` as `RefObject<HTMLDivElement | null>`, which no
longer matches the hook's return shape — the public type signature
needs to follow.

Behavior is unchanged at runtime since the prop is only ever forwarded
to a JSX `ref={...}`, which accepts both ref shapes.

Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
- useChat: ref the `onFinish` callback and pass a stable wrapper to
  `useAiChat`, matching the pattern already used for
  `onData`/`onStreamPart`/`headers`. Consumers can keep passing
  callbacks bound via `useCallback(..., [list, …])` without worrying
  whether the AI SDK rebinds the callback per render.

- agent.route: add a TODO comment on `seedMessages` documenting that
  hydration drops `tool`-role messages and only emits plain `text`
  parts — past tool invocations and approval cards therefore do not
  re-render when a thread is resumed. No behavior change here; the
  proper fix needs a shared Message → UIMessage converter that can be
  reused by `<ChatApp>` as well.

Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
- chat-history-sidebar.groupThreadsByDate: replace setMonth math with
  a fixed 30-day window. The old `setMonth(getMonth() - 1)` overflows
  at end-of-month (e.g. Mar 31 - 1 month rolls to Mar 3 because Feb is
  shorter), bucketing threads into the wrong group on those days. The
  new window also matches the visible "Last 30 days" label.

- chat-history-sidebar: surface delete failures. Adds a `deleteState`
  prop ({ loading, error }) so the confirmation AlertDialog can stay
  open while the delete is in flight, show the error inline if it
  rejects, and disable Cancel/Continue during the request. Continue
  now preventDefaults so it doesn't auto-close on failure. The dialog
  only dismisses on a successful delete.

- chat-app.ChatAppWithHistory: propagate `loading`/`error` from
  `useDeleteThread` into the new `deleteState` prop, and rewrite
  `handleDeleteThread` to re-throw on failure (was swallowed before)
  so the rejection reaches the sidebar.

- chat-app: mirror the hydration TODO comment from `agent.route.tsx`
  onto the matching `seedMessages` block here so the limitation is
  documented at both call sites.

Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
@hubertzub-db hubertzub-db force-pushed the agent/v2/chatui/4-use-chat-history-in-full-ui branch from cbbf25a to 4846fca Compare May 21, 2026 11:25
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