On this page
Overview
Binds six caller-owned provider/model selects with draft-safe hydration, explicit inventory discovery, and paired LLM selection.
- Artifact
AIModelSelectionController.js· esm - Classification
public first party - Availability
Browser / native WebView with supplied select elements - Normalization
Mutable six-slot selection copies preserve complete exact saved values, unknown options, labels, and newer drafts. Caller-owned catalogs merge with existing options; unscoped initial LLM options belong to the initial provider while unscoped explicit catalog entries are shared. LLM provider/model pairing preserves each provider's remembered model, with default-pair, first-enabled-match, or empty selection for a new provider. Explicit hydration and discovery track independent latest operations and retain complete errors. No User writes, storage, model activation, download, polling, or Core call occurs.
Import and lifecycle
import * as module from '/node_modules/arcane-os/runtime/arcane/modules/AIModelSelectionController.js';
Binds native input/change listeners to six caller-owned select elements and updates their options. Hydration and inventory discovery begin only through explicit method calls. Imports and construction perform no storage writes, model activation, downloads, polling, or Core calls. dispose() removes listeners, aborts pending inventory work, and prevents later DOM updates.
Application-facing behavior: Named/default AIModelSelectionController; constructor({selects,defaults,catalogs,inventory}); getSelection(), hydrate(tupleOrPromise), discover(), state, and dispose(). Slot order: llmProvider, sttProvider, ttsProvider, llmModel, ttsModel, sttModel.
Protocol and host implementation
In-process selection state and native input/change events This detail does not widen the application-facing API or grant authority.
Exports, signatures, parameters, and results
| Binding | Form | Declaration or signature | Parameter syntax |
|---|---|---|---|
AIModelSelectionController | class | class AIModelSelectionController | — |
default | default · class | class AIModelSelectionController | — |
| Callable | Kind | Exact public signature | Parameter syntax |
|---|---|---|---|
AIModelSelectionController.getSelection | public-member | getSelection() | — |
AIModelSelectionController.hydrate | public-member | async hydrate(preferences) | preferences |
AIModelSelectionController.discover | public-member | async discover() | — |
AIModelSelectionController.dispose | public-member | dispose() | — |
| Member | Kind | Exact public declaration | Parameter syntax |
|---|---|---|---|
AIModelSelectionController.constructor | constructor | constructor({selects, defaults, catalogs = {}, inventory} = {}) | {selects, defaults, catalogs = {}, inventory} = {} |
AIModelSelectionController.state | get | get state() | — |
AIModelSelectionController.getSelection | method | getSelection() | — |
AIModelSelectionController.hydrate | async method | async hydrate(preferences) | preferences |
AIModelSelectionController.discover | async method | async discover() | — |
AIModelSelectionController.dispose | method | dispose() | — |
Parameter meanings and results
new AIModelSelectionController({selects, defaults, catalogs, inventory}) accepts named llmProvider, sttProvider, ttsProvider, llmModel, ttsModel, and sttModel selects. getSelection() returns a mutable tuple copy in that order. Defaults fall back to the existing select values. Per-slot catalogs merge existing options with caller-owned string or {value,label,provider?,disabled?} entries; LLM catalogs also accept Core {preferenceValue,providerValue,label} descriptors. Initial LLM options without data-provider belong to the initial default provider; explicitly supplied catalog entries without provider are shared. Rendering preserves provider metadata; a new controller needs the complete app catalogs again because the DOM shows only current-provider choices. Unknown values and complete labels remain intact. hydrate(tupleOrPromise) preserves newer input/change drafts, treating the LLM provider and model as one pair; the latest hydration owns settlement. discover() calls the optional inventory({selection,signal}) once, merges returned per-slot catalogs without replacing selections, and supersedes previous discovery. Both methods resolve the current tuple copy, including superseded successful operations; discover without inventory returns it without work. LLM provider changes restore that provider's remembered model, otherwise use its supplied default pair, first enabled matching catalog entry, or an empty value; explicitly saved or remembered disabled selections remain intact. The state getter exposes hydrating, discovering, disposed, hydrationError, and discoveryError. dispose() returns true once and false thereafter, retaining the final readable selection. All persistence, catalogs, defaults, readiness, and activation policy remain application-owned.
Events, side effects, and errors
Source-literal CustomEvent dispatches
No source-literal CustomEvent dispatch is part of this artifact.
Lifecycle and event flow
- consumes native input/change on the supplied selects; emits no custom event
Direct coded failures
This artifact directly assigns no stable coded failure.
Exported Error subclasses
This artifact exports no Error subclass.
Documented failure behavior
- TypeError for missing selects, non-string values or labels, non-array hydration, or a non-function inventory
- Error when starting work after disposal
- Complete caller hydration or inventory rejection
Availability and capabilities
Browser / native WebView with supplied select elements. Mutable six-slot selection copies preserve complete exact saved values, unknown options, labels, and newer drafts. Caller-owned catalogs merge with existing options; unscoped initial LLM options belong to the initial provider while unscoped explicit catalog entries are shared. LLM provider/model pairing preserves each provider's remembered model, with default-pair, first-enabled-match, or empty selection for a new provider. Explicit hydration and discovery track independent latest operations and retain complete errors. No User writes, storage, model activation, download, polling, or Core call occurs.
Browser / native WebView selection only. Optional caller inventory may project Core localAI.status through CoreLocalModelCatalog; the controller neither calls Core nor infers readiness from catalog presence.
Contract example
import AIModelSelectionController from 'arcane-os/modules/AIModelSelectionController.js';
const form = document.querySelector('#model-preferences');
const controller = new AIModelSelectionController(
{
selects: form.elements
}
);
form.addEventListener(
'change',
function showModelSelection() {
document.querySelector('#selected-models').textContent = JSON.stringify(
controller.getSelection()
);
}
);
// Call controller.dispose() when the owning settings view is removed.
Related reference
No direct Core call is claimed for this artifact. Any injected provider or consuming module retains its own documented authority.