ngx-prompt-kit

Model Selector

ngx-prompt-kit original — not part of ibelick/prompt-kit

A composer's model switcher: a compact trigger pill that opens a wide panel with a spartan input-group search, a maker rail, admin-curated sections, price tiers and credit estimates. On phones it becomes a bottom sheet with maker chips, which closes when dragged down by its handle or title.

Examples

In a composer

The panel opens upward, aligned to and as wide as the composer (via [anchor]). Try typing “code”, the arrow keys and Enter, or resize below 768px for the bottom sheet.

Inline, below a centred composer

With [inline], the desktop panel opens in the page's flow instead of floating: the page renders inlinePortal through a cdkPortalOutlet where the panel belongs, here in place of the suggestions under an empty chat's composer. Escape and a click outside close it. Phones still get the bottom sheet.

Installation

Add the model-selector component (and the cn() utility) to your project.

ng generate ngx-prompt-kit:model-selector

It is built on spartan/ui, so add these helm components too: button, input-group, sheet.

ng g @spartan-ng/cli:ui button input-group sheet

Component API

PkModelSelector

PropTypeDefaultDescription
modelsreadonly SelectorModel[] — All selectable models (required). Rail order follows first appearance of each maker.
sectionsreadonly SelectorSection[] [] Curated groups shown under one rail entry above the makers. When present, that entry is selected on open.
valuestring | null null Selected model id. Two-way bindable via [(value)].
anchorElementRef | HTMLElement | null null Element the desktop panel aligns to and matches the width of (e.g. the composer). Without it the panel is 784px wide, aligned to the trigger’s end.
inlineboolean false On desktop, open in the page’s flow instead of a floating panel. The page renders inlinePortal where the panel belongs. Escape and a pointer down outside the panel and trigger close it.
placeholderstring "Select model" Trigger text when nothing is selected.
titlestring "Choose a model" Sheet title and the panel’s accessible name.
sectionsLabelstring "Recommended" Rail entry / chip label for the curated sections.
searchPlaceholderstring "Search by name or what you need, …" Desktop search placeholder.
mobileSearchPlaceholderstring "Search models or what you need" Bottom-sheet search placeholder.
searchLabelstring "Search models" Accessible label of the search field.
railLabelstring "Model makers" Accessible label of the maker rail / chip row.
noResultsTextstring "No models match “{query}”." Empty search text; {query} is substituted.
disabledboolean false Disables the trigger.
classstring — Extra classes for the host.

Outputs & methods

PropTypeDefaultDescription
selected(id: string) => void — Fires when a row is picked. The panel closes and focus returns to the trigger.
openChange(open: boolean) => void — Fires when the panel or sheet opens or closes.
inlinePortalSignal<TemplatePortal | null> — With [inline], the open panel for a cdkPortalOutlet in the page; null while closed.
open() / close()void — Imperative control, e.g. from a keyboard shortcut.

Content projection

PropTypeDefaultDescription
[pkModelSelectorFooter]element — Footer strip content (note + balance). Laid out as a space-between row; use md:hidden / hidden md:inline for phone-specific text.

CSS variables

PropTypeDefaultDescription
--pk-model-selector-rail-fillcolor var(--muted) at 40% Fill of the desktop maker rail and footer, e.g. var(--sidebar) to match a sidebar layout. Set it where the overlay can inherit it, such as :root.

SelectorModel interface

PropTypeDefaultDescription
id / namestring — Identifier and display name (required).
makerstring — Grouping key and rail label, e.g. "Anthropic" (required).
shortNamestring? — Shorter trigger label on phones.
iconUrlstring? — Brand icon; providerIconUrl() from model-icon resolves one from the bundled set.
makerIconUrlstring? — The maker’s own icon for the rail, when a model’s icon is a sub-brand’s (Gemma under Google). Falls back to the first model’s iconUrl.
descriptionstring? — One truncated line under the name. Searched.
capabilitiesreadonly string[]? — Chip labels next to the name. Searched.
priceTier1 | 2 | 3 — Renders $, $$ or $$$.
costLabelstring? — Hint under the price tier, e.g. "≈ 14 credits".
disabledboolean? — Shown dimmed and not selectable.

SelectorSection interface

PropTypeDefaultDescription
id / labelstring — Identifier and group heading.
descriptionstring? — Muted text next to the heading.
modelIdsreadonly string[] — Models in display order; unknown ids are skipped.

priceTier(input, output, thresholds?)

PropTypeDefaultDescription
returns1 | 2 | 3 — Blended price = (3 × input + output) / 4 per 1M tokens; < low → 1, < high → 2, else 3.
thresholdsPartial<{ low; high }> { low: 2.5, high: 10 } Boundaries in your pricing currency. Throws RangeError on negative / non-finite prices.