open-model-selector 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,72 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+ This project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] — 2026-02-06
11
+
12
+ Initial release of `open-model-selector`.
13
+
14
+ ### Added
15
+
16
+ - **`<ModelSelector>` component** — accessible combobox for selecting AI models, built with cmdk and Radix Popover
17
+ - Managed mode: fetches models from any OpenAI-compatible `/v1/models` endpoint
18
+ - Controlled mode: accepts a static `models` array
19
+ - Fuzzy search by name, provider, ID, and description
20
+ - Favorites with localStorage persistence (uncontrolled) or external state (controlled via `onToggleFavorite`)
21
+ - Sorting by name (A-Z) or newest, controllable or uncontrolled
22
+ - "Use System Default" sentinel option (`SYSTEM_DEFAULT_VALUE`)
23
+ - Popover placement (`side` prop: top, bottom, left, right)
24
+ - Custom `placeholder` text
25
+ - `className` and `ref` forwarding
26
+ - Configurable `storageKey` for localStorage namespace isolation
27
+ - `showSystemDefault` toggle
28
+ - `onChange` callback receives the model ID **and** the full model object (`AnyModel | null`) — no secondary lookup needed
29
+ - **`useModels` hook** — fetches and normalizes models from an OpenAI-compatible API
30
+ - `baseUrl` and `apiKey` props for endpoint configuration
31
+ - Custom `fetcher` prop for SSR, proxies, and testing (ref-stored — no memoization needed)
32
+ - Custom `responseExtractor` for non-standard response shapes
33
+ - Custom `normalizer` for non-standard model shapes
34
+ - AbortController cleanup on unmount
35
+ - Re-fetches on `baseUrl` or `apiKey` change
36
+ - **`defaultModelNormalizer`** — handles OpenAI, Venice.ai, and OpenRouter response shapes
37
+ - Extracts provider from slash-separated IDs or `owned_by`
38
+ - Resolves `context_length`, `context_window`, and Venice `model_spec.availableContextTokens`
39
+ - Normalizes pricing from `pricing`, `metadata.pricing`, `cost`, and Venice `model_spec.pricing` formats
40
+ - Falls back to `model_id` when `id` is missing
41
+ - **`defaultResponseExtractor`** — handles `{ data: [...] }`, `{ models: [...] }`, and top-level array responses
42
+ - **`formatPrice`** — formats per-token prices into per-million-tokens dollar strings with adaptive precision
43
+ - **`formatContextLength`** — formats token counts into compact strings (e.g. `128k`, `1M`, `1.5M`)
44
+ - **Separate `open-model-selector/utils` entry point** — pure utility functions without `"use client"` directive, safe for React Server Components
45
+ - Normalizers: `defaultModelNormalizer`, `defaultResponseExtractor`, per-type normalizers (`normalizeTextModel`, `normalizeImageModel`, …)
46
+ - Formatters: `formatPrice`, `formatContextLength`, `formatFlatPrice`, `formatAudioPrice`, `formatDuration`, `formatResolutions`, `formatAspectRatios`
47
+ - Helpers: `isDeprecated`
48
+ - All model types re-exported for normalizer consumers
49
+ - **Scoped CSS** — all variables use `--oms-` prefix; never pollutes `:root` or host app styles
50
+ - Light theme defaults
51
+ - Dark mode via `@media (prefers-color-scheme: dark)` and `.dark` class ancestor
52
+ - Portal-safe dark mode for popover and tooltip content
53
+ - **Model tooltip** — hover over a model name to see description, context length, provider badge, and input/output pricing
54
+ - **Comprehensive test suite** — unit, component (jsdom), and Storybook (Playwright) test projects
55
+ - **Storybook stories** — Default, PreselectedModel, SystemDefault, CustomPlaceholder, SortByNewest, ControlledFavorites, EmptyState, LoadingState, ErrorState, PopoverTop, WideContainer, DarkMode, MinimalModels, and VeniceLive
56
+ - **GitHub Actions CI** — automated npm publish on GitHub release creation
57
+ - **TypeScript** — full type exports (33 types):
58
+ - **Base**: `ModelType`, `BaseModel`, `Deprecation`, `AnyModel`
59
+ - **Text**: `TextModel`, `TextPricing`, `TextCapabilities`, `TextConstraints`
60
+ - **Image**: `ImageModel`, `ImagePricing`, `ImageConstraints`
61
+ - **Video**: `VideoModel`, `VideoConstraints`
62
+ - **Inpaint**: `InpaintModel`, `InpaintPricing`, `InpaintConstraints`
63
+ - **Embedding**: `EmbeddingModel`, `EmbeddingPricing`
64
+ - **TTS**: `TtsModel`, `TtsPricing`
65
+ - **ASR**: `AsrModel`, `AsrPricing`
66
+ - **Upscale**: `UpscaleModel`, `UpscalePricing`
67
+ - **Component / Hook**: `ModelSelectorProps`, `TextModelSelectorProps`, `ImageModelSelectorProps`, `VideoModelSelectorProps`, `UseModelsProps`, `UseModelsResult`, `FetchFn`
68
+ - **Normalizer**: `ModelNormalizer`, `ResponseExtractor`
69
+ - **Dual CJS/ESM output** — built with tsup, sourcemaps and `.d.ts` included
70
+
71
+ [Unreleased]: https://github.com/sethbang/open-model-selector/compare/v0.1.0...HEAD
72
+ [0.1.0]: https://github.com/sethbang/open-model-selector/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Seth Bang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.