ViteHub is still experimental. Expect bugs and breaking changes.
Chat
Render an AI SDK-native message list without coupling presentation to transport.
AgentChat accepts AI SDK UIMessage[] and ChatStatus. It renders messages, preserves reader scroll intent during streaming, and exposes slots for application-specific presentation.
Preview
ChatExample.vue
<script setup lang="ts">
import type { UIMessage } from "ai";
const messages: UIMessage[] = [
{
id: "user-1",
role: "user",
parts: [{ type: "text", text: "Which files changed in the UI package?" }],
},
{
id: "assistant-1",
role: "assistant",
parts: [{
type: "text",
text: "The change updates `AgentInvocationList` and adds a regression test for variable-height error rows.",
}],
},
];
</script>
<template>
<AgentChat :messages="messages" status="ready" class="h-96" />
</template>
Usage
app/pages/chat.vue
<script setup lang="ts">
import { useChat } from "@ai-sdk/vue";
import type { FileUIPart } from "ai";
const { messages, status, sendMessage, stop } = useChat();
const input = ref("");
function submit({ text, files }: { text: string; files: FileUIPart[] }) {
sendMessage({ text, files });
input.value = "";
}
</script>
<template>
<div class="grid h-dvh grid-rows-[1fr_auto]">
<AgentChat :messages :status />
<AgentChatPrompt v-model="input" :status @submit="submit" @stop="stop" />
</div>
</template>
ViteHub's useChat() wrapper has the same UI boundary and supplies the ViteHub route and typed Agent metadata.
Anatomy
<AgentChat>
<template #message="{ message, index }" />
<template #scroll-button />
</AgentChat>
Props
| Prop | Type | Default |
|---|---|---|
messages | readonly UIMessage[] | [] |
status | ChatStatus | 'ready' |
edgeThreshold | number | Global default 8 |
previousItemPeek | number | Global default 64 |
The component does not call sendMessage(), stop(), or regenerate(). Keeping transport outside the rendering tree lets the same UI work with AI SDK, ViteHub Agent routes, persisted sessions, or replayed fixtures.