Pass models and a model pill appears in the
composer. Open the assistant in the corner and pick one.
The widget knows nothing about models: which ones exist, who serves them
and what they cost is the host's business, normally its server's. The
options are plain data, and the chosen id is sent as
model with every message.
createAiChatWidget({
endpoint: "/api/chat",
models: [
{ id: "claude-haiku-4-5-20251001", label: "Haiku 4.5", hint: "Fastest, lightest", cost: "1×" },
{ id: "claude-sonnet-5-5", label: "Sonnet 5.5", hint: "Fast and capable", cost: "2×" },
{ id: "claude-opus-5-5", label: "Opus 5.5", hint: "Most capable", cost: "4×" },
{ id: "claude-fable-5-1", label: "Fable 5.1", hint: "Deepest reasoning", cost: "10×" },
],
defaultModel: "claude-sonnet-5-5",
onModelChange: (id) => console.log("now answering with", id),
});
The last message this page's stub received was sent with: (nothing sent yet)
Give options a group and they are listed under it. Adding
another company's models is a longer list, not a new widget. This button
swaps in an illustrative two-vendor list; the ids are made up.
The choice is remembered per storageNamespace
and layout scope, and checked against the list on every mount: switch
lists and a model the new list does not offer falls back to
defaultModel rather than being sent.