Offer starter prompts and follow-up suggestions, from static config or generated by the runtime.
Suggestions are prompts a user can choose before sending a message or after a response. Configure a list with Suggestions(...), or let the runtime supply the thread's suggestions. The same Vue primitives render either source.
Static suggestions
Pass Suggestions([...]) under the suggestions key of AuiConfig. Each item can be a string or an object with title, label, and prompt. A string uses its text for both title and prompt, with an empty label. The object form separates the text shown to the user from the message sent.
This is an abridged version of the Nuxt example's Assistant.client.vue. Its suggestion config and prompts are unchanged:
<script setup lang="ts">
import { AuiConfig, AuiProvider } from "@assistant-ui/vue";
import { Suggestions } from "@assistant-ui/core/store";
import { AISDKThreads } from "@assistant-ui/ai-sdk";
import Thread from "~/components/assistant-ui/thread.vue";
const config = AuiConfig({
threads: AISDKThreads(),
suggestions: Suggestions([
{
title: "Check the weather",
label: "tool UI demo",
prompt: "What is the weather in San Francisco right now?",
},
{
title: "Explain streaming",
label: "how token streaming works",
prompt: "Explain how token streaming works in chat UIs.",
},
{
title: "Write a haiku",
label: "about the terminal",
prompt: "Write a haiku about the terminal.",
},
]),
});
</script>
<template>
<AuiProvider :config="config">
<Thread />
</AuiProvider>
</template>Suggestions from the runtime
When the suggestions key is absent, the suggestions scope follows s.thread.suggestions. The AI SDK runtime accepts a suggestions option through AISDKChat or AISDKThreads, and an external store runtime can supply its own suggestion array. Runtime entries need a prompt; title defaults to that prompt and label defaults to an empty string when they enter the suggestions scope.
For example, AISDKChat({ suggestions: [{ prompt: "What happened next?" }] }) supplies a thread suggestion. A configured Suggestions([...]) entry replaces runtime suggestions in the suggestions scope, so ThreadPrimitiveSuggestions renders the configured list in that case.
Generated follow-ups
Pass a suggestion adapter under the AI SDK runtime's adapters option to generate follow-ups after a run. createSuggestionAdapter builds a prompt from recent message text and calls your complete function. It requests three prompts from up to ten recent messages by default, trims blank results, and maps the returned strings to thread suggestions. Forward the optional abort signal to the request.
<script setup lang="ts">
import { AuiConfig, AuiProvider } from "@assistant-ui/vue";
import { AISDKChat } from "@assistant-ui/ai-sdk";
import { createSuggestionAdapter } from "@assistant-ui/core";
import Thread from "~/components/assistant-ui/thread.vue";
const config = AuiConfig({
threads: AISDKChat({
adapters: {
suggestion: createSuggestionAdapter({
async complete({ prompt, signal }) {
const response = await fetch("/api/suggestions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt }),
signal,
});
if (!response.ok) throw new Error("Suggestion request failed");
return (await response.json()) as string[];
},
}),
},
}),
});
</script>
<template>
<AuiProvider :config="config">
<Thread />
</AuiProvider>
</template>The endpoint returns an array of prompt strings. This Nuxt route uses the same AI SDK model setup as the example chat route:
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
export default defineEventHandler(async (event) => {
const { prompt } = await readBody<{ prompt: string }>(event);
const { text } = await generateText({
model: openai("gpt-6-luna"),
prompt,
});
return text.split("\n").map((line) => line.trim()).filter(Boolean);
});The AI SDK runtime clears adapter suggestions when a new run starts. When a run ends, it calls the adapter only if the last message is from the assistant and does not require an action. The adapter's results replace s.thread.suggestions. When an adapter is configured, its results take precedence over the runtime's suggestions option.
Render them
The registry thread.vue renders ThreadPrimitiveSuggestions in the empty state as starter prompts. For follow-ups, render the same primitives after a response, when the thread is not empty or running. Static Suggestions([...]) entries stay in the suggestions scope at both placements; omit that entry when the post-response list should come from the runtime.
<AuiIf :condition="(s) => !s.thread.isEmpty && !s.thread.isRunning">
<div class="flex flex-wrap gap-2">
<ThreadPrimitiveSuggestions>
<SuggestionPrimitiveTrigger send>
<SuggestionPrimitiveTitle />
</SuggestionPrimitiveTrigger>
</ThreadPrimitiveSuggestions>
</div>
</AuiIf>This is an abridged rendering fragment; import AuiIf, ThreadPrimitiveSuggestions, SuggestionPrimitiveTrigger, and SuggestionPrimitiveTitle from @assistant-ui/vue in its component. See Suggestion for the parts and click behavior.