@assistant-ui/vue
Not published yet. This package is the in-repo preview of the Vue bridge and stays private until the Vue integration is complete.
Vue bindings for assistant-ui. Bridges the framework-neutral @assistant-ui/store client into Vue via <AuiProvider>, useAui, useAuiState, and useAuiEvent.
The runtime layer runs on @assistant-ui/tap, a headless hooks runtime that needs no React renderer. Alias react to @assistant-ui/tap/standalone-shim in your bundler so the shared runtime code resolves without React installed:
// vite.config.ts
export default defineConfig({
resolve: {
alias: {
"react/compiler-runtime": "@assistant-ui/tap/standalone-shim/compiler-runtime",
react: "@assistant-ui/tap/standalone-shim",
},
},
});
Usage
<!-- Root.vue -->
<script setup lang="ts">
import { AuiProvider, AuiConfig } from "@assistant-ui/vue";
import Composer from "./Composer.vue";
import { ComposerScope, ThreadScope } from "./scopes";
const config = AuiConfig({
thread: ThreadScope(),
composer: ComposerScope(),
});
</script>
<template>
<AuiProvider :config="config"><Composer /></AuiProvider>
</template>
<!-- Composer.vue -->
<script setup lang="ts">
import { useAui, useAuiState } from "@assistant-ui/vue";
const aui = useAui();
const isRunning = useAuiState((s) => s.thread.isRunning);
</script>
<template>
<button :disabled="isRunning" @click="aui.composer.send()">Send</button>
</template>
useAui returns a stable client whose scope accessors always resolve to the provider's current client. useAuiState returns a computed ref that updates when the selected slice changes by Object.is. useAuiEvent subscribes to assistant events for the lifetime of the current effect scope.
Primitives
Headless components for runtime-backed threads, mirroring the React primitives. Mount a runtime with RuntimeAdapter from @assistant-ui/core/store and compose:
ThreadPrimitiveMessagesrenders its default slot once per thread message, each instance scoped throughMessageByIndexProvider(descendants reads.messageand the message's edit composer ass.composer).ComposerPrimitiveInputis a textarea bound to the composer text; Enter submits, Shift+Enter inserts a newline, IME composition is ignored.ComposerPrimitiveSendandComposerPrimitiveCancelare buttons wired to the composer with the same disabled semantics as the React primitives.ThreadPrimitiveViewportis a scroll container that keeps the thread pinned to the bottom while the user is at the bottom, scrolls down on run start, and unpins when the user scrolls up. It provides the scroll channelThreadPrimitiveScrollToBottomdrives: a button, placed inside the viewport, that jumps back down and disables while already at the bottom.MessagePrimitivePartsrenders the current message's content parts, each scoped throughPartByIndexProvider; a slot named after the part type overrides its rendering, and text parts render their text by default.BranchPickerPrimitivePrevious/Next/Number/Countnavigate and display message branches.ActionBarPrimitiveEdit,ActionBarPrimitiveReload, andActionBarPrimitiveCopycover the widget-free message actions; inside a message scope the composer primitives double as the edit UI (beginEditseeds the edit composer,ComposerPrimitiveSendsaves into a new branch,ComposerPrimitiveCanceldiscards).ThreadPrimitiveSuggestionsrenders the default slot once per configured suggestion (Suggestions([...])from@assistant-ui/core/storein the provider config), scoped throughSuggestionByIndexProvider;SuggestionPrimitiveTriggersends the prompt (send) or inserts it into the composer, andSuggestionPrimitiveTitle/Descriptionrender its text.ThreadListPrimitiveItemsrenders the default slot once per thread (scoped throughThreadListItemByIndexProvider), withThreadListPrimitiveNew,ThreadListItemPrimitiveTrigger, andThreadListItemPrimitiveTitle(default slot orfallbackstring when the title is empty) covering the sidebar basics; the runtime supplies the list through the external-storeadapters.threadList.AuiIfrenders its slot while a state selector returns true.
<script setup lang="ts">
import {
ComposerPrimitiveInput,
ComposerPrimitiveSend,
ThreadPrimitiveMessages,
} from "@assistant-ui/vue";
import ChatMessage from "./ChatMessage.vue";
</script>
<template>
<ol>
<ThreadPrimitiveMessages>
<ChatMessage />
</ThreadPrimitiveMessages>
</ol>
<ComposerPrimitiveInput placeholder="Say something" />
<ComposerPrimitiveSend>Send</ComposerPrimitiveSend>
</template>
examples/with-vue/src/Root.vue shows the RuntimeAdapter mount this composes with.
See examples/with-vue in the repository for a complete Vite setup, or examples/with-nuxt for a Nuxt app that streams real responses from a Nitro server route.