Model Selector
A searchable model picker for chat. The button shows the model's logo and name. The list has a search field and shows each model with its logo, a short description, and three colored meters for speed, quality, and cost, rated against the other models in the list.
In a composer
Speed, quality, and cost are rated 1 to 5 against the other models in the list.
Ask anything…
Using Claude Sonnet 5.5
Without numbers
Leave out speed, quality, and cost and the meters go away. Logos and search stay.
Usage
import { ModelSelector } from "@tulipfarm/sprout/model-selector";
const models = [
{ id: "opus", label: "Claude Opus 5.5", description: "Hardest problems", brand: "claude", speed: 45, quality: 92, cost: 75 },
{ id: "gpt", label: "GPT-5.5", description: "Writing and analysis", brand: "openai", speed: 70, quality: 90, cost: 30 },
{ id: "deepseek", label: "DeepSeek V4", description: "Cheap and capable", brand: "deepseek", speed: 60, quality: 82, cost: 1.1 },
];
const [model, setModel] = useState("opus");
<ModelSelector models={models} value={model} onValueChange={setModel} />brand draws the vendor logo from Brand Icon. Pass icon for any other mark; with neither, the first letter of label stands in. side and align place the list, and label (default Model) names the button and heads the first column.
Speed, quality, and cost
Pass raw numbers in any unit, such as tokens per second for speed, an eval score for quality, and dollars per million tokens for cost. Higher means faster, better, or pricier. Each meter rates the model from 1 to 5 between the lowest number in the list (1) and the highest (5), so prices never show. When every model has the same number, they all get 3.
Hover a column heading to see what it measures and what one to five bars mean, from slowest to fastest, weakest to strongest, or cheapest to priciest.
A model missing a number shows a dash for it. When no model has numbers, the meters and their headings go away. rateModels(models) returns the same ratings if you need them elsewhere.
In Chat Input
Chat Input uses Model Selector for its models picker. Give its models speed, quality, and cost to show the meters there too. Pass render to use your own button, as Chat Input does with InputGroupButton.
Motion
The list grows from the button and the chevron turns over. On the highlighted and chosen rows the meters take their full color, filling left to right. With reduced motion, the list only fades and the meters change at once.
Accessibility
The button and list are a Base UI combobox with its search field inside the list. Opening moves focus to the search; typing filters by name, description, or vendor, arrow keys move, Enter picks, and Escape closes and returns focus to the button. The button reads “Model: Claude Opus 5.5”. Each option reads its name, description, and ratings, such as “Speed 1 of 5, slowest. Quality 5 of 5, strongest. Cost 5 of 5, priciest.” The column headings and their hover tooltips are hidden from screen readers, since each option names its own ratings. In forced colors, meters draw in system colors.
Theme tokens
Set --sprout-model-selector-speed, --sprout-model-selector-quality, and --sprout-model-selector-cost on :root to recolor the meters, since the list renders in a portal. They default to --sprout-green, --sprout-blue, and --sprout-orange. Other rows show those colors at 40%. The list uses --sprout-surface, --sprout-line, and --sprout-radius-panel, like Select.