Skip to Content
Components

Model picker

Pick a model by speed, quality and cost, and how hard it thinks.

A trigger names the picked model and how hard it thinks, over the open list of models. Each shows its speed, quality and cost as five-step meters, with the real numbers (speedDetail, qualityDetail, costDetail) on hover. The thinking effort sits under them as a small dropdown. A model that can't take the request can set a status of checking or busy and offer a way out through suggestion — a short notice with its own buttons, the last one filled.

Preview
Model for this chat
ThinkingUp to 8k thinking tokens

Usage

<!-- include core.css + model-picker.css + model-picker.js -->
<div class="card" data-c="model-picker">
  <div class="mpk">
    <div class="mpk-top">
      <span class="muted mpk-lb">Model for this chat</span>
      <button class="mpk-tr" aria-haspopup="true" aria-expanded="true">
        <span class="mpk-mk"></span><span class="mpk-nm"></span>
        <span class="mpk-ef muted"></span>
      </button>
    </div>
    <div class="fold mpk-fold"><div><div class="mpk-p panel">
      <div class="mpk-list" role="radiogroup" aria-label="Model"></div>
    </div></div></div>
  </div>
</div>

Properties

NameTypeDescription
modelsModelOption[]The models to choose from.
valuestringThe picked model's id. Leave it out to let the list hold its own.
defaultValuestringThe picked model's id to start on when uncontrolled.
onValueChange(id) => voidCalled when a row is picked, busy or not, so you can check the model first.
effortsThinkingEffort[]The thinking efforts. Defaults to Off, Low, Medium and High.
effort / defaultEffortstringThe picked effort's label, controlled or to start on.
onEffortChange(effort) => voidCalled when the effort changes.
suggestion{ text; actions: { label; onClick }[] }A way out when the picked model can't take the request. The last button is filled.
notestringThe confirmation under the picker, shown with a green check.
labelstringThe label beside the trigger. Defaults to "Model for this chat".
open / defaultOpenbooleanWhether the list is open. Leave it out to let the trigger and Escape open and close it.
onOpenChange(open) => voidCalled when the list opens or closes.
ModelOption.speed/quality/costnumberEach from 1 to 5. For cost, 5 is the most expensive.
ModelOption.statusready | checking | busychecking spins beside the name; busy turns the row amber, both showing statusText.

Theming

Works in light and dark (data-theme="dark") and in the Soft style (data-style="soft"). The trigger and panel sit on a surface with the card shadow; each model's tile takes its own color with a letter colour that reads on it, the picked row's filled meters take the accent, and a busy row and its notice take the warn tint — all from the theme tokens, so it reads against the dark stage.

On this page