Chords
Major Chords

FollowUpSuggestions

Dynamic suggestion chips that appear after assistant messages.

Overview

FollowUpSuggestions renders contextual suggestion buttons based on the runtime's thread.suggestions state. Unlike SuggestionChips which shows static welcome-screen suggestions, this component displays dynamic follow-up prompts generated by the runtime after each assistant response.

Demo

When to use

  • Show dynamic follow-up questions after assistant responses
  • Help users discover related topics or actions
  • Auto-hide during streaming and when no suggestions exist
  • Commonly placed after the last assistant message or at the bottom of the viewport

Features

  • Dynamic suggestions: Reads from thread.suggestions state provided by the runtime
  • Auto-hide: Hidden when thread is running or when no suggestions exist
  • Auto-send: Clicks send the suggestion immediately by default
  • Customizable: Override chip styling or provide a custom renderer

Props

PropTypeDefaultDescription
classNamestring-Container class
chipClassNamestring-Suggestion chip class
autoSendbooleantrueSend message immediately on click
renderChipfunction-Custom chip renderer

Basic Usage

import { FollowUpSuggestions } from "@assistant-ui/chords";

export function MyThread() {
  return (
    <ThreadPrimitive.Root>
      <ThreadPrimitive.Viewport>
        <ThreadPrimitive.Messages components={{ ... }} />
        <FollowUpSuggestions />
      </ThreadPrimitive.Viewport>
    </ThreadPrimitive.Root>
  );
}

Providing Suggestions via Runtime

Follow-up suggestions are provided by a SuggestionAdapter on the runtime:

const runtime = useLocalRuntime(MyModelAdapter, {
  adapters: {
    suggestion: {
      async *generate({ messages }) {
        const suggestions = await fetchSuggestions(messages);
        yield suggestions.map((text) => ({ prompt: text }));
      },
    },
  },
});

Custom Chip Renderer

<FollowUpSuggestions
  renderChip={(prompt, index) => (
    <button key={index} className="my-custom-chip">
      {prompt}
    </button>
  )}
/>

Custom Styling

<FollowUpSuggestions
  className="flex flex-wrap gap-3 justify-center"
  chipClassName="rounded-lg bg-blue-500/20 px-4 py-2 text-sm hover:bg-blue-500/30"
/>

SuggestionChips vs FollowUpSuggestions

SuggestionChipsFollowUpSuggestions
Data sourceStatic array you provideDynamic from runtime
When shownWelcome screen (empty thread)After assistant responses
PlacementInside ThreadPrimitive.EmptyAfter messages in viewport

Migration Notes

TODO: migrate to store — useThreaduseAuiState(({ thread }) => thread)

On this page