<AgentInterface> props
Every prop of AgentInterface, grouped by area (adapters, rendering, theme, branding, starters, routing, scrolling, and children).
AgentInterface from @openuidev/react-ui is the only chat component you mount. It owns the layout: sidebar, thread list, composer, routing, and the workspace rail. You configure all of it through AgentInterfaceProps. This page lists every prop, grouped by what it controls.
The only required prop is llm. Everything else is optional and falls back to a sensible default.
At a glance
| Prop | Type | Required | Default |
|---|---|---|---|
llm | ChatLLM | Yes | none |
storage | ChatStorage | No | internal in-memory (ephemeral) |
artifactRenderers | ReadonlyArray<ArtifactRendererConfig<any>> | No | none |
artifactCategories | ArtifactCategory[] | No | none (single "Artifacts" item) |
artifactAutoOpen | boolean | No | true |
componentLibrary | Library | No | none (markdown rendering) |
onAction | (event: ActionEvent) => void | No | none |
components | AgentInterfaceComponents | No | none |
theme | ThemeProps | No | built-in theme |
disableThemeProvider | boolean | No | false |
logoUrl | string | No | none |
agentName | string | No | none |
labels | AgentInterfaceLabels | No | built-in labels |
starters | ConversationStarterProps[] | No | none |
starterVariant | "short" | "long" | "card" | No | none |
path | string | No | none (uncontrolled) |
defaultPath | string | No | thread view (undefined) |
onNavigate | (next: string | undefined) => void | No | none (uncontrolled) |
scrollVariant | "always" | "once" | "user-message-anchor" | No | "user-message-anchor" |
scrollOnLoad | boolean | No | true |
children | ReactNode | No | none |
The rest of this page explains each group.
Adapters
These two props connect AgentInterface to your backend. They are independent channels: llm produces replies, storage persists threads and artifacts.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
llm | ChatLLM | Yes | none | Sends messages to your backend and streams the reply. |
storage | ChatStorage | No | internal in-memory (ephemeral) | Persists thread history (and, optionally, artifacts). |
llm is a ChatLLM, usually built with fetchLLM(). fetchLLM() POSTs { threadId, messages } to your route and parses the streamed response. See Conversations for the model, and the Adapters & formats reference for the full ChatLLM / fetchLLM() surface and the stream adapters that parse each provider's stream.
storage is a ChatStorage: { thread: ThreadStorage; artifact?: ArtifactStorage }. Omit it and conversations live only in memory: a page refresh clears everything. Build one with restStorage(), or implement the interfaces yourself. The full adapter interfaces (ChatLLM, ChatStorage, ThreadStorage, ArtifactStorage, fetchLLM, restStorage) are in the Adapters & formats reference.
The provider API call always happens on your server. fetchLLM() only ever talks to your own
route, so provider keys never reach the browser.
Rendering
These props control how the assistant's output renders: artifacts such as dashboards and apps, and the message body.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
artifactRenderers | ReadonlyArray<ArtifactRendererConfig<any>> | No | none | Renderers that display artifacts (from a tool call or from stored content). |
artifactCategories | ArtifactCategory[] | No | none | User-defined groupings for the artifact browser and workspace rail. |
artifactAutoOpen | boolean | No | true | Opens a new artifact in the workspace panel while it streams. At most one per reply. |
componentLibrary | Library | No | none | Turns on Generative UI: components rendered inline in chat. |
onAction | (event: ActionEvent) => void | No | none | Receives the Generative UI actions the chat does not handle, such as custom actions. |
components | AgentInterfaceComponents | No | none | Replace assistant answers, user messages, and the turn's tool timeline independently. |
artifactRenderers
Each entry is built with defineArtifactRenderer and links a tool name (or names) to a preview (inline in the message) and an actual (full view in the workspace panel or a full-page artifact view). The registry indexes by both toolName and type. See the defineArtifactRenderer reference.
import { AgentInterface, defineArtifactRenderer } from "@openuidev/react-ui";
const codeArtifact = defineArtifactRenderer({
type: "code_artifact",
toolName: "create_code_artifact",
parser: (raw, ctx) => /* ... */ null,
preview: (props, controls) => /* ... */ null,
actual: (props, controls) => /* ... */ null,
});
<AgentInterface llm={llm} artifactRenderers={[codeArtifact]} />;artifactCategories
Categories group artifacts in the artifact browser. They do not depend on whether an artifact is static or live. Each is { name: string; filter: { type: string[] } }. Without categories, the sidebar shows a single "Artifacts" item; with them, one item per category.
<AgentInterface
llm={llm}
storage={storage}
artifactCategories={[
{ name: "Code", filter: { type: ["code_artifact"] } },
{ name: "Dashboards", filter: { type: ["dashboard"] } },
]}
/>componentLibrary
Pass a library (e.g. openuiLibrary from @openuidev/react-ui/genui-lib) to enable Generative UI: the LLM renders rich, interactive components inline in chat messages, beyond markdown. This is distinct from artifacts (durable outputs in panels and pages). See Generative UI.
import { AgentInterface } from "@openuidev/react-ui";
import { openuiLibrary } from "@openuidev/react-ui/genui-lib";
<AgentInterface llm={llm} componentLibrary={openuiLibrary} />;onAction
AgentInterface handles two actions of Generative UI components itself: @ToAssistant sends a new user message and @OpenUrl opens the link in a new tab. Those never reach onAction. onAction receives the other actions, such as the custom actions your componentLibrary defines.
<AgentInterface
llm={llm}
componentLibrary={library}
onAction={(event) => {
if (event.type === "CopyToClipboard") {
void navigator.clipboard.writeText(String(event.params.text));
}
}}
/>onAction is only called for messages that AgentInterface renders from componentLibrary. When you pass components.AssistantMessage, it is not called. Pass onAction to the Renderer in your component instead.
components
Override the message components directly: { AssistantMessage?, ToolCallTimeline?, UserMessage? }. Message rendering precedence is components > componentLibrary > built-in default, so an explicit components entry always wins. See Message rendering.
Theme
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
theme | ThemeProps | No | built-in theme | Customizes colors, radii, and typography. |
disableThemeProvider | boolean | No | false | Skip the built-in theme provider when your app already supplies one. |
Set disableThemeProvider to true when AgentInterface is mounted inside an app that already wraps it in a compatible theme provider, to avoid nesting two.
Branding
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
logoUrl | string | No | none | Logo shown in the sidebar header and the mobile header. |
agentName | string | No | none | Agent name shown next to the logo. |
labels | AgentInterfaceLabels | No | built-in labels | Text for the artifact browser and workspace: { defaultCategory?, workspaceToggle?, tabs? }. |
These feed the default SidebarHeader and MobileHeader. To go further, replace those slots. See Sidebar.
Starters
Conversation starters are the suggested prompts shown on the welcome screen and in the composer.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
starters | ConversationStarterProps[] | No | none | Suggested prompts to seed a conversation. |
starterVariant | "short" | "long" | "card" | No | none | Layout variant for how starters are presented. |
Each starter is { displayText: string; prompt: string; icon?: ReactNode }. displayText is the label on the suggestion chip and prompt is the message sent when it is clicked. These props set the defaults for the Welcome and Composer slots; either slot can also take its own starters / starterVariant. See Welcome & starters.
Routing
AgentInterface has a built-in router. undefined is the thread view; non-undefined paths select Routes and the artifact browser.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | No | none (uncontrolled) | Controlled current route. |
defaultPath | string | No | thread view (undefined) | Uncontrolled initial route. |
onNavigate | (next: string | undefined) => void | No | none (uncontrolled) | Navigation callback; its presence selects controlled mode. |
Controlled mode is chosen by the presence of onNavigate, not by path !== undefined, because undefined is a valid path (the thread view). In controlled mode, drive path from your own router and update it inside onNavigate. In uncontrolled mode, set an initial route with defaultPath and let the component manage navigation internally.
Controlled consumers must round-trip the reserved artifact-browser paths (artifacts/{category} and artifacts/{category}/{id}), which are matched before your own AgentInterface.Route entries. Read the current route and navigate from anywhere inside the component with the useNav() hook (from @openuidev/react-ui).
// Uncontrolled: open on a specific route at mount.
<AgentInterface llm={llm} defaultPath="settings" />;
// Controlled: drive the route from your own state/router.
<AgentInterface llm={llm} path={path} onNavigate={setPath} />;Scrolling
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
scrollVariant | "always" | "once" | "user-message-anchor" | No | "user-message-anchor" | "user-message-anchor" pins the latest user message to the top. "always" follows the reply to the bottom until the user scrolls up. "once" scrolls to the bottom once when a message is added. |
scrollOnLoad | boolean | No | true | Scroll to the latest message when a thread loads or the user switches threads. |
Children
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | ReactNode | No | none | Slots, primitives, Routes, and free content. |
children is where composition happens. Pass the compound statics on AgentInterface: slots (AgentInterface.Sidebar, .Welcome, .Composer, .Workspace, and so on), primitives (AgentInterface.SidebarItem, .ThreadList, .Messages, and so on), and AgentInterface.Route for multi-page content. Slots not provided fall back to their built-in defaults. See the Components reference.
<AgentInterface llm={llm}>
<AgentInterface.Welcome
title="What can I help with?"
description="Ask about your data or build a dashboard."
/>
<AgentInterface.Route path="settings">
<SettingsPanel />
</AgentInterface.Route>
</AgentInterface>Related references
- Adapters & formats:
ChatLLM,ChatStorage,ThreadStorage,ArtifactStorage,fetchLLM,restStorage, the stream adapters, and the message formats used to buildllmandstorage. defineArtifactRenderer: the shape of eachartifactRenderersentry.- Hooks:
useNav,useThread,useArtifactStorage, and the rest. - Components: the slots and primitives you pass as
children.