Documents
model-selector
model-selector
Type
External
Status
Published
Created
Mar 17, 2026
Updated
Apr 2, 2026
Updated by
Dosu Bot

import { ModelSelectorSample } from "@/components/docs/samples/model-selector";

A select component that lets users switch between AI models. Uses item-aligned positioning so the selected model overlays the trigger for a unified look. Integrates with assistant-ui's ModelContext system to automatically propagate the selected model to your backend.

Getting Started#

Add model-selector#

<InstallCommand shadcn={["model-selector"]} />

Use in your application#

Place the ModelSelector inside your thread component, typically in the composer area:

import { ModelSelector } from "@/components/assistant-ui/model-selector";

const ComposerAction: FC = () => {
  return (
    <div className="flex items-center gap-1">
      <ModelSelector
        models={[
          { id: "gpt-4o-mini", name: "GPT-4o Mini", description: "Fast and efficient" },
          { id: "gpt-4o", name: "GPT-4o", description: "Balanced performance" },
          { id: "o3", name: "o3", description: "Most capable" },
        ]}
        defaultValue="gpt-4o-mini"
        size="sm"
      />
    </div>
  );
};

Read the model in your API route#

The selected model's id is sent as config.modelName in the request body:

export async function POST(req: Request) {
  const { messages, config } = await req.json();

  const result = streamText({
    model: openai(config?.modelName ?? "gpt-4o"),
    messages: await convertToModelMessages(messages),
  });

  return result.toUIMessageStreamResponse();
}

Variants#

Use the variant prop to change the trigger's visual style.

<ModelSelector variant="outline" /> // Border (default)
<ModelSelector variant="ghost" /> // No background
<ModelSelector variant="muted" /> // Solid background
VariantDescription
outlineBorder with transparent background (default)
ghostNo background, subtle hover
mutedSolid secondary background

Sizes#

Use the size prop to control the trigger dimensions.

<ModelSelector size="sm" /> // Compact (h-8, text-xs)
<ModelSelector size="default" /> // Standard (h-9)
<ModelSelector size="lg" /> // Large (h-10)

Model Options#

Each model in the models array supports:

const models = [
  {
    id: "gpt-4o", // Sent to backend as config.modelName
    name: "GPT-4o", // Display name in trigger and items
    description: "Most capable", // Optional subtitle in items only
    icon: <SparklesIcon />, // Optional icon (any ReactNode)
  },
];

Runtime Integration#

The default ModelSelector export automatically registers the selected model with assistant-ui's ModelContext system. When a user selects a model:

  1. The component calls aui.modelContext().register() with config.modelName
  2. The AssistantChatTransport includes config in the request body
  3. Your API route reads config.modelName to determine which model to use

This works out of the box with @assistant-ui/react-ai-sdk.

API Reference#

Composable API#

For custom layouts, use the sub-components directly with ModelSelector.Root:

import {
  ModelSelectorRoot,
  ModelSelectorTrigger,
  ModelSelectorContent,
  ModelSelectorItem,
} from "@/components/assistant-ui/model-selector";

<ModelSelectorRoot models={models} value={modelId} onValueChange={setModelId}>
  <ModelSelectorTrigger variant="outline" />
  <ModelSelectorContent />
</ModelSelectorRoot>
ComponentDescription
ModelSelectorDefault export with runtime integration
ModelSelector.RootPresentational root (no runtime, controlled state)
ModelSelector.TriggerCVA-styled trigger showing current model
ModelSelector.ContentSelect content with model items
ModelSelector.ItemIndividual model option with icon, name, description

ModelSelector#

<ParametersTable
type="ModelSelectorProps"
parameters={[
{
name: "models",
type: "ModelOption[]",
required: true,
description: "Array of available models to display.",
},
{
name: "defaultValue",
type: "string",
description: "Initial model ID for uncontrolled usage.",
},
{
name: "value",
type: "string",
description: "Controlled selected model ID.",
},
{
name: "onValueChange",
type: "(value: string) => void",
description: "Callback when selected model changes.",
},
{
name: "variant",
type: '"outline" | "ghost" | "muted"',
default: '"outline"',
description: "Visual style of the trigger button.",
},
{
name: "size",
type: '"sm" | "default" | "lg"',
default: '"default"',
description: "Size of the trigger button.",
},
{
name: "contentClassName",
type: "string",
description: "Additional class name for the dropdown content.",
},
]}
/>

ModelOption#

<ParametersTable
type="ModelOption"
parameters={[
{
name: "id",
type: "string",
required: true,
description: "Unique identifier sent to the backend as modelName.",
},
{
name: "name",
type: "string",
required: true,
description: "Display name shown in trigger and dropdown.",
},
{
name: "description",
type: "string",
description: "Optional subtitle shown below the model name.",
},
{
name: "icon",
type: "React.ReactNode",
description: "Optional icon displayed before the model name.",
},
]}
/>