arcane-os 0.67.0 → 0.69.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.
@@ -112,7 +112,7 @@ snapshot remains owned until the browser's `afterprint` event.
112
112
  | [`task-progress.html`](#task-progresshtml) | Runs and displays a task list with started/change/complete/error state. | `configure()`<br>`setTasks()`<br>`updateTask()`<br>`runTasks()`<br>`clear()`<br>`destroy()` | `task-progress-ready`<br>`task-progress-started`<br>`task-progress-change`<br>`task-progress-complete`<br>`task-progress-error` | Task state normalized; injected task results mixed |
113
113
  | [`terminal-workspace.html`](#terminal-workspacehtml) | Presents multiple terminal sessions, output, active selection, theme, and terminal actions. | `configure()`<br>`addSession()`<br>`removeSession()`<br>`activateSession()`<br>`append()`<br>`clear()`<br>`setState()`<br>`setTheme()`<br>`focus()`<br>`destroy()` | `terminal-workspace-ready`<br>`terminal-submit`<br>`terminal-interrupt`<br>`terminal-clear`<br>`terminal-session-new`<br>`terminal-session-close`<br>`terminal-session-select`<br>`terminal-settings` | UI/session state normalized; native command results supplied externally |
114
114
  | [`theme-editor.html`](#theme-editorhtml) | Edits, previews, saves, and resets semantic custom theme tokens. | `configure()`<br>`getTheme()`<br>`setTheme()`<br>`setBusy()`<br>`setStatus()`<br>`destroy()` | `theme-editor-ready`<br>`theme-preview`<br>`theme-save`<br>`theme-reset` | Fully normalized Theme values |
115
- | [`theme-switcher.html`](#theme-switcherhtml) | Selects and refreshes system, light, dark, or custom theme mode. | `setMode()`<br>`refresh()` | No component-specific event | Preference/native appearance behavior mixed; no component-ready contract |
115
+ | [`theme-switcher.html`](#theme-switcherhtml) | Selects and refreshes system, light, dark, or custom theme mode with per-instance choices and labels. | `configure()`<br>`setMode()`<br>`refresh()` | No component-specific event | Preference/native appearance behavior mixed; no component-ready contract |
116
116
  | [`unified-inbox.html`](#unified-inboxhtml) | Displays provider-neutral communication threads with active/loading state. | `configure()`<br>`setThreads()`<br>`setActive()`<br>`setLoading()`<br>`destroy()` | `unified-inbox-ready`<br>`inbox-refresh`<br>`thread-select` | DOM-normalized |
117
117
  | [`voice-transcription.html`](#voice-transcriptionhtml) | Records manual clips or optional continuous microphone audio with pause/periodic segments, ordered transcription and saves, retained failures, and complete transcript delivery. | `configure()`<br>`requestSTTActivation()`<br>`startRecording()`<br>`stopRecording()`<br>`retryTranscription()`<br>`cancelRecording()`<br>`save()`<br>`completeTranscription()/complete()`<br>`clear()`<br>`reset()`<br>`destroy()` | `voice-transcription-ready`<br>`voice-transcription-state`<br>`voice-transcription-segment`<br>`voice-transcription-empty`<br>`voice-transcription-error`<br>`voice-transcription-change`<br>`voice-transcription-complete`<br>`speech-transcription-complete`<br>`speech-transcription-cancelled`<br>`speech-stt-activation-request`<br>`speech-stt-activation-error` | Sticky STT readiness, capture/queue lifecycle, retry, cancellation, and complete state/text are normalized; media/provider behavior remains external |
118
118
  | [`weather-widget.html`](#weather-widgethtml) | Displays normalized current and daily weather with refresh intent. | `setWeather()`<br>`clear()`<br>`destroy()` | `weather-widget-ready`<br>`weather-refresh` | Display normalized; provider supplied externally |
@@ -2015,11 +2015,63 @@ Shared dependencies: [`Theme.js`](runtime-entities.md#themejs).
2015
2015
 
2016
2016
  ### Overview
2017
2017
 
2018
- Selects and refreshes system, light, dark, or custom theme mode.
2018
+ Selects and refreshes system, light, dark, or custom theme mode. Native buttons
2019
+ retain complete readable labels and wrap when their component runs out of room,
2020
+ independently of viewport width. Each button has a `2.75rem` minimum target in
2021
+ both dimensions. Selected buttons retain `aria-pressed`, their selected colors
2022
+ and an inset outline while hovered; ordinary hover fill applies only to
2023
+ unselected, enabled choices. Disabled choices and keyboard focus have distinct
2024
+ presentation.
2019
2025
 
2020
2026
  ### Public surface
2021
2027
 
2022
- Methods/properties: `setMode()`, `refresh()`.
2028
+ Methods/properties: `configure(options)`, `setMode(mode='system')`, `refresh()`.
2029
+
2030
+ `configure({modes,labels})` changes only this component's presentation:
2031
+
2032
+ - `modes` is an ordered array of the available identifiers `system`, `light`,
2033
+ `dark`, and `custom`. It selects both visible choices and DOM/keyboard order.
2034
+ Omitted `modes` retains the current presentation; an empty array displays no
2035
+ choices. Unknown or repeated identifiers throw `TypeError` before changing
2036
+ the presentation.
2037
+ - `labels` is a partial record of complete string labels keyed by those mode
2038
+ identifiers. Omitted labels keep their current text. Text is assigned through
2039
+ `textContent`, never interpreted as markup or reduced to initials. A label for
2040
+ a built-in mode that is not a string throws `TypeError`.
2041
+ - The return value is `{modes,labels}` containing independent mutable copies of
2042
+ the current presentation. Later changes to supplied/returned records do not
2043
+ reconfigure the component.
2044
+
2045
+ Label-only and unchanged-order configuration retain the existing buttons in
2046
+ place. An actual reorder restores keyboard focus to the previously focused
2047
+ button when that choice remains visible and enabled, without scrolling.
2048
+
2049
+ The default remains Auto / Light / Dark / Skin, using identifiers
2050
+ `system`, `light`, `dark`, and `custom`. A caller may omit Skin or change Auto's
2051
+ label to System without removing custom-theme support from other instances.
2052
+ Configuration never changes preferences, activates a theme, or replaces the
2053
+ current selected mode. If the active mode is omitted, no visible button claims
2054
+ to be selected. Restoring that choice restores its existing pressed and disabled
2055
+ state. Skin remains disabled until the manager has a saved custom theme.
2056
+
2057
+ For the initial presentation, `data-modes` accepts whitespace-separated mode
2058
+ identifiers and `data-system-label` supplies the complete system-mode label.
2059
+ These attributes are read once before the asynchronous ThemeManager import and
2060
+ preference refresh, so initial choices do not wait for `html-import-ready`.
2061
+ Use `configure()` after that event for subsequent presentation changes;
2062
+ changing these attributes later does not reconfigure an existing instance.
2063
+
2064
+ `setMode()` updates pressed state and the host's `data-mode` only. `refresh()`
2065
+ loads the existing ThemeManager state, updates selection and Skin availability,
2066
+ and resolves with the complete manager state. Clicking a choice uses the same
2067
+ manager persistence/activation operation; buttons remain disabled while that
2068
+ operation is pending. Presentation configuration preserves that pending state.
2069
+
2070
+ The host inherits text color. Existing `--app-bar-border` (falling back to
2071
+ `--border-color`), `--app-bar-accent` (then `--secondary-color`),
2072
+ `--app-bar-active-text` (then `--primary-color`), and `--focus-color` overrides
2073
+ remain supported. Applications own their palette and surrounding placement;
2074
+ the component adds no application-specific palette or settings section.
2023
2075
 
2024
2076
  This fragment declares no component-specific readiness or action event; use the loader's `html-import-ready` only to know that import execution completed.
2025
2077
 
@@ -2033,11 +2085,18 @@ Shared dependencies: [`ThemeManager.js`](runtime-modules.md#thememanagerjs).
2033
2085
 
2034
2086
  ```html
2035
2087
  <html-import
2036
- id="theme-switcher.html"
2037
- href="/arcane/components/theme-switcher.html">
2088
+ id="theme-switcher"
2089
+ href="/node_modules/arcane-os/runtime/arcane/components/theme-switcher.html"
2090
+ data-modes="light dark system"
2091
+ data-system-label="System">
2038
2092
  </html-import>
2039
2093
  ```
2040
2094
 
2095
+ This instance displays Light / Dark / System in that order. An instance without
2096
+ the two configuration attributes retains all four default choices. Both use
2097
+ the existing shared preference owner; presentation does not create a new store
2098
+ or migrate saved themes.
2099
+
2041
2100
  ## unified-inbox.html
2042
2101
 
2043
2102
  ### Overview
@@ -120,7 +120,7 @@ own asynchronous work, cancellation, and backpressure.
120
120
  | [`OllamaSettings.js`](#ollamasettingsjs) | esm | Defines complete runtime/service preference schemas and deterministic Arcane brain alias names. | Cross-host | Fully normalized settings/name contract. |
121
121
  | [`OpenMeteoWeatherProvider.js`](#openmeteoweatherproviderjs) | esm | Searches and loads Open-Meteo data into complete mutable Arcane weather entities. | Browser / native WebView / server with fetch + cloud | Provider data normalized to mutable entities; transport errors mixed. |
122
122
  | [`PersistentAIChatSession.js`](#persistentaichatsessionjs) | esm | Adds explicit retained-history/memory policy to complete configured chat without changing DBOPFS or ChatEntity semantics. | Browser / native WebView with DBOPFS and configured chat | Retained context commits atomically; `persist:false` turns are one-operation-only. |
123
- | [`PreferenceStore.js`](#preferencestorejs) | esm | Loads and updates schema-defined app preferences through native storage with a narrow browser fallback. | Browser/native hybrid | Complete ordinary values remain mutable; setAll uses one optional atomic adapter batch for every selected value when advertised, otherwise performs complete ordered serial writes, and only exact unsupported native capability changes future operations to the browser fallback. |
123
+ | [`PreferenceStore.js`](#preferencestorejs) | esm | Loads and updates schema-defined app preferences through native storage with a narrow browser fallback. | Browser/native hybrid | Complete values and operation context retained; exact optional namespace absence or existing Android unsupported capability selects the existing local adapter; partial-service and genuine failures remain errors; an advertised rejected batch is never retried serially. |
124
124
  | [`PreparedSpeech.js`](#preparedspeechjs) | esm | Owns detached ordered preparation, semantic audio reuse, and per-caller cancellation behind AI.prepareTTS. | Browser / native WebView with injected synthesis and optional DBOPFS | Complete original inputs, ordered audio metadata, durable reuse, and observable preparation results. |
125
125
  | [`PrintView.js`](#printviewjs) | esm | Prints current rendered content and title through one document-owned print lifecycle. | Browser / supported native WebView print implementation | Complete rendered snapshot, preparation cancellation, resource lifetime, and honest request result. |
126
126
  | [`QRCode.min.js`](#qrcodeminjs) | classic-script | Vendored QRCode generator for DOM, canvas, SVG, and image output. | Browser vendor script | Vendor-native. |
@@ -134,7 +134,7 @@ own asynchronous work, cancellation, and backpressure.
134
134
  | [`ScreenCapture.js`](#screencapturejs) | esm | Captures a display surface as image, video, or GIF with explicit lifecycle events. | Browser / native WebView | State/events normalized; permission and codec errors mixed. |
135
135
  | [`SpeechPlayback.js`](#speechplaybackjs) | esm | Admits complete speech segments to a capacity-advertising provider immediately, retains serialized native/custom lookahead, and plays every result in exact indexed order. | Browser + native bridge | Stored part text stays exact; the outbound speech-input copy receives automatic formatting-mark cleanup; provider/media failures remain mixed. |
136
136
  | [`StaticDocumentCatalog.js`](#staticdocumentcatalogjs) | esm | Loads a positive static document inventory with cache, search, and complete context. | Browser / native WebView / server with fetch | Mutable complete catalog/content normalization; malformed data and transport failures remain visible. |
137
- | [`SystemAppearance.js`](#systemappearancejs) | esm | Reads or applies native appearance, returning an explicit unsupported browser state when no bridge exists. | Browser/native hybrid | Absent bridge normalized; native result/error preserved. |
137
+ | [`SystemAppearance.js`](#systemappearancejs) | esm | Reads or applies native appearance, returning an explicit unsupported result when the bridge or optional namespace is absent. | Browser/native hybrid | Exact absent optional namespace normalized with its complete error; partial-method and genuine native errors preserved. |
138
138
  | [`SystemPlatformPresentation.js`](#systemplatformpresentationjs) | classic-script | Maps kernel names to presentation labels/classes without granting platform authority. | Browser / native WebView classic script | Fully normalized presentation only. |
139
139
  | [`SystemToolRegistry.js`](#systemtoolregistryjs) | esm | Registers validated command builders and constructs command strings without executing them. | Cross-host | Fully normalized definitions/quoting. |
140
140
  | [`TerminalClient.js`](#terminalclientjs) | esm | Maps native terminal sessions and Arcane events into an EventTarget client. | Native bridge | Client events/state normalized; native result/error mixed. |
@@ -170,7 +170,7 @@ default `AI`; read-only `providerRuntime`, `speechActivationPending`, `browserSp
170
170
  `streamRequest()`, `streamMessage()`, `fetchRequest()`, `fetch()`,
171
171
  read-only `ttsSegmentation`, `configureTTSSegmentation()`,
172
172
  `streamTTS(text='',end=false,options={})`,
173
- `prepareTTS({parts,storage,identity,signal,onState})`,
173
+ `prepareTTS({parts,textFormat,storage,identity,signal,onState})`,
174
174
  `playPreparedTTS(prepared,{signal,onState})`,
175
175
  `finishTTS()`, `prepareTTSPlayback()`, `fetchTTS()`, `fetchSTT()`, `stopAudio()`, `resumeAudio()`,
176
176
  `playAudio()`; consumes `user-entity-loaded` and `arcane-ollama-ready`,
@@ -393,14 +393,17 @@ synthesis payload to `Arcane.speech.synthesize(request, {signal})`; Core aborts
393
393
  are normalized to `AbortError` with `ARCANE_AI_REQUEST_ABORTED`. Actual engine
394
394
  interruption belongs to the registered service. It does not independently
395
395
  choose a provider, cloud fallback, model, runtime, or
396
- voice policy for the application. Every call removes repeated same formatting
397
- marks from a cloned outbound input before delegation; the caller's payload stays
398
- unchanged. The third `preparation` argument is reserved for SDK-internal
396
+ voice policy for the application. By default, calls remove repeated same
397
+ formatting marks from a cloned outbound input before delegation; the caller's
398
+ payload stays unchanged. Public payload field `textFormat:'plain'` preserves
399
+ the complete input, including whitespace and repeated marks. The SDK consumes
400
+ that field before provider/host dispatch. Omission and other values retain the
401
+ default cleanup. The third `preparation` argument is reserved for SDK-internal
399
402
  delegation, where `{speechInputPrepared:true}` prevents a second cleanup pass;
400
403
  applications omit it. `streamTTS(text='',end=false,options={})` and
401
404
  `finishTTS()` use the selected playback boundary. The third-argument options below
402
- are available in SDK `0.5.12`. The `textFormat` compatibility extra added in
403
- SDK `0.5.16` is ignored beginning in `0.5.17`:
405
+ are available in SDK `0.5.12`. In these streaming options, the `textFormat`
406
+ compatibility extra added in SDK `0.5.16` remains ignored:
404
407
 
405
408
  | Field | Default | Meaning |
406
409
  | --- | --- | --- |
@@ -408,7 +411,7 @@ SDK `0.5.16` is ignored beginning in `0.5.17`:
408
411
  | `speed` | Current `ai.voiceSpeed` | A supplied positive speed is captured for those segments and forwarded to `fetchTTS()`. It does not change `ai.voiceSpeed`. |
409
412
  | `pauseAfterMs` | `0` | Finite, nonnegative milliseconds placed after the final extracted segment on the existing audio clock. Invalid values throw `RangeError`; no pause is inserted between this call's other segments. |
410
413
  | `waitForPlayback` | `false` | Omission retains the preparation promise. With `true`, the promise resolves after every extracted segment reaches a terminal playback state: `true` when all naturally end, or `false` after terminal cancellation or failure. |
411
- | `textFormat` | Ignored compatibility extra | Repeated same formatting marks are removed automatically from every TTS call. This value no longer selects or disables cleanup. |
414
+ | `textFormat` | Ignored streaming compatibility extra | Streaming narration retains automatic cleanup. The public plain selection belongs to complete synthesis payloads or `prepareTTS` options. |
412
415
 
413
416
  Audio-file voice and speed use the existing `fetchTTS()` validation and error path.
414
417
  The automatic cleanup changes only the outbound speech-input copy; displayed,
@@ -418,7 +421,7 @@ text, single marks, ordinary punctuation, and other characters remain literal.
418
421
  A trailing candidate mark waits for the next character so a repeated run split
419
422
  across chunks is still omitted. Ordinary prose streams immediately.
420
423
  `end:true`, `finishTTS()`, muted terminal calls, and `stopAudio()` clear pending
421
- formatting state. `textFormat` is not an opt-out.
424
+ formatting state. Streaming `textFormat` is not an opt-out.
422
425
 
423
426
  Voice, speed, pause, and playback overrides belong to the segments
424
427
  extracted in that invocation, including any text buffered by an earlier call.
@@ -458,12 +461,16 @@ last audio buffer ends, without waiting out that pause. Completion describes
458
461
  the playback lifecycle, not proof that a listener heard the sound. See the
459
462
  [complete-passage example](ai/browser-speech.md#queue-complete-passages-and-wait-for-playback).
460
463
 
461
- `prepareTTS({parts,storage,identity,signal,onState})` returns an immediate
464
+ `prepareTTS({parts,textFormat,storage,identity,signal,onState})` returns an immediate
462
465
  `{segments,state,ready,getAudio(index),cancel()}` handle for detached complete
463
466
  speech preparation. Parts are strings or `{input,voice?,speed?,pauseAfterMs?}`
464
467
  records. It retains the full source for semantic matching, snapshots the
465
468
  selected speech configuration and segmentation, and applies automatic
466
- formatting cleanup once to the speech copy. Generation uses the existing
469
+ formatting cleanup once to the speech copy by default. `textFormat:'plain'`
470
+ preserves each complete input before the same ordered segmentation. Prepared
471
+ segment text participates in reuse, keeping cleaned and exact synthesis inputs
472
+ distinct when they differ. This SDK text-treatment choice does not change the
473
+ selected engine's own input capacity. Generation uses the existing
467
474
  bounded provider queue without adding playback. Optional
468
475
  `storage:{db,table,key}` saves complete audio files and their MIME metadata in
469
476
  the caller's ready DBOPFS instance; the separate JSON-compatible `identity`
@@ -1032,9 +1039,12 @@ records are the closed `{llm,stt,tts}`, `{stt,tts}`, or
1032
1039
  `{providers,routes,expectedProviders}` shapes described below.
1033
1040
  `configureFromTuple()` accepts exactly six provider/model preference entries.
1034
1041
 
1035
- Every direct TTS `request()` or `synthesize()` call removes repeated same
1036
- formatting marks from a cloned outbound payload's `input` or `text` field. The
1037
- caller's payload and request records remain unchanged. The optional
1042
+ By default, direct TTS `request()` and `synthesize()` remove repeated same
1043
+ formatting marks from a cloned outbound payload's `input` or `text` field.
1044
+ Public payload field `textFormat:'plain'` preserves that input exactly. The SDK
1045
+ consumes this field before queuing/dispatch; queued requests retain their
1046
+ selected text treatment. Omission and other values keep the default cleanup.
1047
+ The caller's payload and request records remain unchanged. The optional
1038
1048
  `preparation` argument is reserved for SDK-owned delegation;
1039
1049
  `{speechInputPrepared:true}` prevents a second pass after another SDK speech
1040
1050
  boundary has already cleaned the copy. Applications omit that argument. LLM
@@ -3475,9 +3485,31 @@ Exact exports: `PREFERENCE_STORE_ERROR_CODES`,
3475
3485
 
3476
3486
  **Browser/native hybrid.** Complete ordinary values and returned snapshots remain
3477
3487
  mutable after schema normalization. Non-Android
3478
- `Arcane.preferences.setMany()` supplies the optional atomic batch. Only exact
3479
- unsupported native capability changes future operations to app-scoped
3480
- localStorage; an in-flight advertised batch is never downgraded after rejection.
3488
+ `Arcane.preferences.setMany()` supplies the optional atomic batch. The default
3489
+ adapter uses the existing app-scoped localStorage owner when there is no native
3490
+ preferences facade, on the existing Android route, or after either the existing
3491
+ `ANDROID_CAPABILITY_UNSUPPORTED` error or an exact Core lookup error:
3492
+ `code:'METHOD_NOT_ALLOWED'`, `reason:'core-namespace-unavailable'`,
3493
+ `namespace:'preferences'`, and `method:'preferences.<current operation>'`.
3494
+ This marker proves the entire optional namespace was absent before dispatch.
3495
+ A missing method in a partial/read-only service, an older unmarked error,
3496
+ permission denial, persistence failure, transport error, or cancellation never
3497
+ selects local storage. Explicit caller adapters retain their own behavior.
3498
+
3499
+ For `get`, `set`, and `delete`, that positively absent namespace retries the
3500
+ same operation once through the existing local adapter, then keeps that adapter
3501
+ for the store's later operations. Complete arguments and the existing
3502
+ `{operationId,signal}` context are retained. Disposal and caller cancellation
3503
+ are checked before selecting or invoking the local adapter, so a late native
3504
+ absence result cannot start a cancelled local write. No data location, schema,
3505
+ saved value, or migration is introduced.
3506
+
3507
+ An in-flight advertised `setMany` batch is never downgraded to serial writes
3508
+ after rejection. Exact namespace absence selects the local adapter for later
3509
+ operations and preserves that batch's original rejection with no local write.
3510
+ ThemeManager's first Light/Dark/System choice uses two ordinary `set` calls,
3511
+ not a batch: both may complete through the existing local owner before the
3512
+ selected theme is applied. Its persistence-first ordering is unchanged.
3481
3513
  If cancellation settles after a native batch was dispatched, reload the store to
3482
3514
  reconcile any atomic host commit that completed before cancellation. Transport:
3483
3515
  Arcane.preferences or app-scoped localStorage. [Deep protocol details](protocols.md).
@@ -4064,7 +4096,8 @@ console.log(Object.keys(module));
4064
4096
 
4065
4097
  ### Overview
4066
4098
 
4067
- Reads or applies native appearance, returning an explicit unsupported browser state when no bridge exists.
4099
+ Reads or applies native appearance, returning an explicit unsupported result
4100
+ when the bridge or its optional namespace is absent.
4068
4101
 
4069
4102
  ### Public surface
4070
4103
 
@@ -4074,7 +4107,21 @@ Exact exports: `default`.
4074
4107
 
4075
4108
  ### Availability and normalization
4076
4109
 
4077
- **Browser/native hybrid.** Absent bridge normalized; native result/error preserved. Transport: Arcane.appearance. [Deep protocol details](protocols.md).
4110
+ **Browser/native hybrid.** No bridge or callable method retains the existing
4111
+ `{supported:false,platform:'browser'}` result. A callable facade is not proof of
4112
+ an installed service: `available()` reports callable `apply` presence only.
4113
+ `current()` and `apply()` recognize only a matching Core
4114
+ `METHOD_NOT_ALLOWED` error with `reason:'core-namespace-unavailable'`,
4115
+ `namespace:'appearance'`, and the exact requested method. They return
4116
+ `{supported:false,reason:'core-namespace-unavailable',error}`, retaining the
4117
+ complete original error for diagnostics and making no platform or native
4118
+ application claim. Absence is not cached, so later service registration can
4119
+ serve the next operation. Partial-method absence, unmarked permission errors,
4120
+ transport/cancellation failures and all other native errors reject unchanged.
4121
+ Native success values and existing appearance input normalization remain
4122
+ unchanged. ThemeManager may therefore complete a browser color-scheme change
4123
+ when native appearance is explicitly unsupported, while genuine failures stay
4124
+ observable. Transport: Arcane.appearance. [Deep protocol details](protocols.md).
4078
4125
 
4079
4126
  ### Example
4080
4127
 
@@ -69,6 +69,8 @@ runtime layouts.
69
69
  | `arcane-os/core/local-ai` | Native llama.cpp, Ollama and ONNX Core service, model readiness, complete responses and owned lifecycle. See [local AI through Core](local-ai.md). |
70
70
  | `arcane-os/local-ai` | Official runtime installation and native artifact bundling for selected llama.cpp/Ollama/ONNX/image requirements and NeMo libraries. |
71
71
  | `arcane-os/local-ai/onnx` | Retained native ONNX worker sessions with explicit graph loading and complete tensor inference. |
72
+ | `arcane-os/local-ai/decisions` | Explicit native Laya FP32 decisions using the existing ONNX owner and a tokenizer Worker. |
73
+ | `arcane-os/core/decisions` | Renderer-independent typed-decision service composed with existing local-AI and model-assets owners. |
72
74
  | `arcane-os/ai/core-onnx` | Optional browser access to system ONNX through an existing Core connection. |
73
75
  | `arcane-os/local-ai/image` | Retained native stable-diffusion.cpp context, complete PNG generation and owned worker lifetime. |
74
76
  | `arcane-os/ai/core-image` | Browser image lifecycle and complete PNG Blobs through an available Core service. |
@@ -169,6 +171,9 @@ The remaining data-only subpaths are eight JSON Schemas and package metadata.
169
171
  | `acceptWebSocket()` | function | `arcane-os`, `arcane-os/websocket` | WebSocket protocol | Node; browser-native client interoperability |
170
172
  | `WS` | class | `arcane-os`, `arcane-os/websocket-client` | Shared WebSocket clients | Node and native-WebSocket browser hosts |
171
173
  | `createBrowserDecisionModel()` | function | `arcane-os/ai/browser-decisions` | Browser typed decisions | Browser module Workers and the caller-selected inference backend |
174
+ | `createNativeDecisionModel()` | function | `arcane-os/local-ai/decisions` | Native typed decisions | Node with an existing native ONNX owner and selected Laya FP32 files |
175
+ | `createNativeDecisionService()` | function | `arcane-os/core/decisions` | Native typed decisions | Node Core with existing local-AI and model-assets services |
176
+ | `createNativeDecisionService default export` | function | `arcane-os/core/decisions` | Native typed decisions | Same native decision service factory |
172
177
  | `fetchRequest()` | function | `arcane-os/ai/twin-cloud` | TWiN Cloud requests | Node and Browser; remote HTTPS provider |
173
178
  | `fetchSystemOneRequest()` | function | `arcane-os/ai/twin-cloud` | TWiN Cloud state-and-questions requests | Node and Browser; remote HTTPS provider |
174
179
  | `generateImages()` | function | `arcane-os/ai/twin-cloud` | TWiN Cloud image generation | Node and Browser with Fetch and Blob; remote HTTPS provider |
@@ -1901,6 +1906,20 @@ default class PreferenceStore extends EventTarget
1901
1906
  subpath and managed browser key both resolve directly to the canonical runtime
1902
1907
  module. Deep protocol: [Browser runtime delivery](protocols.md#browser-runtime-delivery).
1903
1908
 
1909
+ The default adapter recognizes an absent optional preferences namespace only
1910
+ from the exact Core lookup tuple `code:'METHOD_NOT_ALLOWED'`,
1911
+ `reason:'core-namespace-unavailable'`, `namespace:'preferences'`, and the
1912
+ matching `method:'preferences.<operation>'`. Single `get`, `set`, and `delete`
1913
+ operations then retry once through the existing app-scoped local adapter after
1914
+ checking disposal and cancellation, preserving complete values and operation
1915
+ context. The existing Android unsupported-capability route is unchanged.
1916
+ An advertised `setMany` batch rejected for that exact absence retains its
1917
+ original rejection and performs no serial retry; subsequent operations use the
1918
+ selected local adapter.
1919
+ Partial-service, permission, persistence, transport and cancellation failures
1920
+ remain errors. Explicit adapters retain their own behavior. See the
1921
+ [complete PreferenceStore contract](runtime-modules.md#preferencestorejs).
1922
+
1904
1923
  ### Example
1905
1924
 
1906
1925
  ```javascript
@@ -7297,9 +7316,18 @@ createCoreRuntime({application, version, services=[]}={})
7297
7316
  ```
7298
7317
 
7299
7318
  Import it from `arcane-os/core/runtime`. The runtime exposes `current()`,
7300
- `subscribe()`, `onFrame()`, `emit()`, `registerService()`, `start()`, `handle()`
7319
+ `subscribe()`, `onFrame()`, `emit()`, `registerService()`, `getService()`, `start()`, `handle()`
7301
7320
  and idempotent `close()`.
7302
7321
 
7322
+ `await runtime.getService(name)` and service `context.getService(name)` return
7323
+ the actual registered service after its shared startup. They wait for that
7324
+ dependency alone, may start it before `runtime.start()`, and add no renderer or
7325
+ all-service barrier. Unknown services reject with `CORE_SERVICE_UNAVAILABLE`;
7326
+ new lookups during shutdown reject with `CORE_CLOSING`. Startup failures retain
7327
+ their original error. This is readiness, not a lifetime lease: retain acquired
7328
+ native handles for their actual cleanup rather than looking them up during
7329
+ disposal. See [native service composition](core-runtime.md#native-service-composition).
7330
+
7303
7331
  Services start independently. Request-lifetime work receives cooperative
7304
7332
  cancellation; accepted `lifetime:'service'` work survives renderer cancellation.
7305
7333
  Shutdown stops admission, waits accepted responses, then runs each service's
@@ -7311,6 +7339,15 @@ without restarting services. Its snapshot preserves complete service errors
7311
7339
  and active request state; see [runtime replay](core-runtime.md#state-and-frames)
7312
7340
  for authoritative readiness and reentrant lifecycle ordering.
7313
7341
 
7342
+ An unregistered method returns `METHOD_NOT_ALLOWED` with its exact `method`,
7343
+ first dotted `namespace`, and `reason:'core-namespace-unavailable'` when that
7344
+ namespace has neither a named service nor any registered method. Otherwise
7345
+ the reason is `core-method-unavailable`; built-in `system`, `app` and `version`
7346
+ namespaces count as present. This is a lookup result before handler or
7347
+ permission decisions. Handler/startup errors and older unmarked errors do not
7348
+ establish namespace absence. The dispatcher does not choose a replacement
7349
+ service; optional browser adapters own their documented response to absence.
7350
+
7314
7351
  ### Availability and normalization
7315
7352
 
7316
7353
  **Node on Windows, Linux and macOS native hosts; Android requires its native host
@@ -8011,7 +8048,7 @@ Construction selects no model and installs no runtime or transport.
8011
8048
  ### Signature and result
8012
8049
 
8013
8050
  ```text
8014
- createCoreLocalAIProvider({client=getInstalledCoreClient(),id='llama.cpp'}={})
8051
+ createCoreLocalAIProvider({client,id='llama.cpp'}={})
8015
8052
  ```
8016
8053
 
8017
8054
  Import it from `arcane-os/ai/core-local`. The provider implements
@@ -8023,6 +8060,16 @@ payloads and parsed streaming chunks, and cancel on observed readiness loss.
8023
8060
  Missing Core reports unavailability; it does not choose a browser or cloud route.
8024
8061
  Dispose/unregister at the caller's owning lifecycle boundary.
8025
8062
 
8063
+ Omitted `client` follows late installation, replacement and retirement through
8064
+ the shared Core installation subscription. An explicit client, including
8065
+ `null`, remains fixed. Replacement revokes readiness and cancels owned work;
8066
+ late results cannot restore it. `inspect()` distinguishes explicit load
8067
+ capability from loaded readiness, while `status()` remains observational.
8068
+ Disposal releases only an actually retained selection through its captured
8069
+ client, so never-loaded and already-unloaded providers send no native unload.
8070
+ The provider/2 runtime reconciles status at its operation boundaries; this
8071
+ does not add an idle role-state subscription.
8072
+
8026
8073
  ```javascript
8027
8074
  import {createCoreLocalAIProvider} from 'arcane-os/ai/core-local';
8028
8075
  import {getAIProviderRuntime} from 'arcane-os/ai-provider-runtime';
@@ -8055,6 +8102,13 @@ resolved installed runtime records. It returns a Core service definition with
8055
8102
  existing Core lifecycle. Shutdown cancels owned work and joins owned processes;
8056
8103
  an already running external service remains under its external owner.
8057
8104
 
8105
+ After `await context.getService('local-ai')`, `service.getONNXRuntime()` returns
8106
+ that service's actual prepared ONNX owner. It creates no engine and rejects
8107
+ unavailable or closing access. Reacquire on each explicit load after recovery;
8108
+ retain the returned handle for cleanup. Core shutdown cancels request-lifetime
8109
+ work, and independent services dispose concurrently. See
8110
+ [native service owners](local-ai.md#native-service-owners).
8111
+
8058
8112
  Optional `prepare({signal,onEvent})` supplies resolved runtime records during
8059
8113
  this service's startup. Only operations depending on that service wait for its
8060
8114
  preparation; the development listener and independently composed image/model
@@ -8064,7 +8118,10 @@ requirements. The managed development and native entrypoints separate them.
8064
8118
 
8065
8119
  The service provides `localai.status`, explicit `localai.services.recover`,
8066
8120
  `llama.status/models/load/unload/chat`, `onnx.status/load/run/unload`, and the documented native Ollama methods.
8067
- `localai.state` reports runtime/model changes. `llama.chunk` and `ollama.chunk`
8121
+ `localai.state` reports runtime/model changes. `llama.status` and `llama.models`
8122
+ observe current state without starting, restarting or waiting for an engine.
8123
+ Explicit load retains startup and exact catalog-membership checks.
8124
+ `llama.chunk` and `ollama.chunk`
8068
8125
  carry original parsed chunks with `streamId`; terminal responses remain complete.
8069
8126
  There is no background health polling or implicit model choice.
8070
8127
 
@@ -8081,7 +8138,7 @@ and [native bundling](local-ai.md#native-bundling).
8081
8138
 
8082
8139
  `createONNXRuntime({modulePath,signal?,onEvent?})` from `arcane-os/local-ai/onnx`
8083
8140
  owns retained native ONNX sessions in workers. It exposes `load({id,model,
8084
- sessionOptions?,signal?})`, `run({id,feeds,fetches?,runOptions?,signal?})`,
8141
+ sessionOptions?,executionPreference?,signal?})`, `run({id,feeds,fetches?,runOptions?,signal?})`,
8085
8142
  `unload({id,signal?})`, `current()`, replaying `subscribe(listener)` and `close()`.
8086
8143
  The direct model path is absolute. Complete typed tensor records use
8087
8144
  `{type,dims,data}`; callers own the actual graph's inputs and preprocessing.
@@ -8091,11 +8148,22 @@ before replacement. Independent sessions run concurrently; same-session work
8091
8148
  waits at that session's loading/execution boundary. Queued cancellation removes
8092
8149
  that request; active cancellation retires the affected worker and suppresses
8093
8150
  its response. Native code can delay termination; cleanup waits for actual exit.
8151
+ `current().sessions[].stopping` revokes new-run availability at terminal
8152
+ shutdown; `exited` records actual Worker exit. A recoverable run error leaves
8153
+ the loaded session usable. Unload joins exit and output delivery even when a
8154
+ termination request fails, preserving the complete cleanup error.
8155
+
8156
+ The generic load defaults to CPU. `executionPreference:'gpu'` tries advertised
8157
+ CUDA, TensorRT, DirectML, CoreML and WebGPU session creation before CPU.
8158
+ Explicit `sessionOptions.executionProviders` takes precedence unchanged.
8159
+ The complete `execution` record reports discovery, provider attempts and
8160
+ fallback; successful creation establishes configuration, not physical GPU
8161
+ execution. Inference is never replayed on a different provider after failure.
8094
8162
  See [complete signatures, readiness, cancellation and usage](local-ai.md#native-onnx-sessions).
8095
8163
 
8096
8164
  ## createCoreONNXRuntime()
8097
8165
 
8098
- `createCoreONNXRuntime({client=getInstalledCoreClient()}={})` from
8166
+ `createCoreONNXRuntime({client}={})` from
8099
8167
  `arcane-os/ai/core-onnx` accesses an available Core ONNX service. Its `load`,
8100
8168
  `run`, and `unload` mirror the native session selection and accept `signal` and
8101
8169
  `timeoutMs` (default `0`). Relative model paths resolve at Core's `appRoot`.
@@ -8103,7 +8171,11 @@ The accessor owns complete tensor transport encoding/decoding, `inspect()`,
8103
8171
  `current()`, replaying `subscribe(listener)` and `close()`. Closing cancels this
8104
8172
  accessor's requests and subscriptions; unloading shared models is explicit.
8105
8173
  Construction installs no runtime and opens no transport. Existing browser
8106
- ONNX/Wllama remain independent. See [Core and browser usage](local-ai.md#onnx-through-core-and-the-browser).
8174
+ ONNX/Wllama remain independent. Omitted `client` follows late installation and
8175
+ reads each installed connection's current status; explicit clients, including
8176
+ `null`, remain fixed. Retirement or replacement clears readiness and cancels
8177
+ owned work, with late old-client results suppressed. Close also removes the
8178
+ installation subscription. See [Core and browser usage](local-ai.md#onnx-through-core-and-the-browser).
8107
8179
 
8108
8180
  ## createImageRuntime()
8109
8181
 
@@ -8143,12 +8215,18 @@ browser accessor's detach-only ownership below. See the
8143
8215
 
8144
8216
  ## createCoreImageRuntime()
8145
8217
 
8146
- `createCoreImageRuntime({client=getInstalledCoreClient(),signal?,onEvent?})`
8218
+ `createCoreImageRuntime({client,signal?,onEvent?})`
8147
8219
  from `arcane-os/ai/core-image` returns immediately with `load`, `generate`, `edit`,
8148
8220
  `unload`, `inspect`, `current`, `subscribe` and `close`. It subscribes before
8149
8221
  requesting an initial status snapshot so newer lifecycle events win. It opens
8150
8222
  no connection and installs or selects no model.
8151
8223
 
8224
+ Omitted `client` follows late Core installation, replacement and retirement;
8225
+ an explicit client, including `null`, remains fixed. Each installed client is
8226
+ observed before its status request. Retirement cancels owned work and removes
8227
+ old readiness; late results cannot restore it. Close removes both service and
8228
+ installation subscriptions without closing the shared client or model.
8229
+
8152
8230
  `load({model,context?,assetProjectionId?,resourcePaths?,signal?})` and
8153
8231
  `generate({model,prompt,parameters?,assetProjectionId?,resourcePaths?,signal?,
8154
8232
  onProgress?})` use the selected Core service. Generation acknowledges with
@@ -8445,6 +8523,14 @@ directory and complete member files.
8445
8523
 
8446
8524
  `current()` returns `{closing,projections}`. `retain(id)` accepts a completed
8447
8525
  projection and returns `{id,directory,members,release}` for a native owner.
8526
+ Native `prepare({id,workingDirectory,members,signal,onProgress})` accepts
8527
+ ordered `{path,url}` members and returns their ready projection. Explicit calls
8528
+ stream complete upstream responses through the same file owner; startup
8529
+ downloads nothing. Independent members transfer concurrently and progress
8530
+ reports phases and completed files. `release(id)` relinquishes preparation
8531
+ ownership; cancellation, release and disposal join fetches and writes before
8532
+ cleanup. Native retain handles keep completed files alive until actual engine
8533
+ release. See [native preparation](model-assets.md#native-ownership).
8448
8534
  `dispose()` releases preparation ownership and joins file writes, closes and
8449
8535
  all native retain lifetimes before cleanup. The native owner releases its
8450
8536
  handle only after its actual context/worker use ends. Original stored model
@@ -9106,6 +9192,110 @@ See the [mounting contract](pwa.md#mountpwainstallprompt) and
9106
9192
  [component reference](runtime-components.md#pwa-installhtml). The browser owns
9107
9193
  native installation eligibility and URL-bar promotion.
9108
9194
 
9195
+ ## createNativeDecisionModel()
9196
+
9197
+ ### Overview
9198
+
9199
+ Runs explicitly selected Laya FP32 option scoring through an existing native
9200
+ ONNX owner, with tokenization in a Node Worker. It creates no second inference
9201
+ engine and starts no model download at construction.
9202
+
9203
+ ### Signature and result
9204
+
9205
+ ```text
9206
+ createNativeDecisionModel({onnx,modelAssets,workingDirectory,paths,model='onnx-community/laya-typed-decisions-ONNX',revision='main',dtype='fp32',sessionOptions,executionPreference='gpu',signal}={})
9207
+ ```
9208
+
9209
+ Import from `arcane-os/local-ai/decisions`. Supply the existing `onnx` owner and
9210
+ either `modelAssets` plus `workingDirectory`, or native `paths` for the model,
9211
+ tokenizer and tokenizer configuration. The selected graph requires FP32. The
9212
+ handle exposes `load`, `evaluate`, `classify`, `current`, `status`, `subscribe`,
9213
+ `unload` and terminal `dispose`; `classify` aliases `evaluate` and `status`
9214
+ aliases `current`.
9215
+
9216
+ `evaluate(rows,{signal,runOptions})` preserves each complete `state`, `question`,
9217
+ `options` and optional `type` separately. It returns `{decisions,outputs}` with
9218
+ original rows, typed values, raw logits, unrounded probabilities and every
9219
+ named tensor output. It requires a loading or loaded activation. Cancellation
9220
+ retires the shared activation and joins its actual ONNX/tokenizer lifetime;
9221
+ working files remain retained until both Workers exit. Ordinary invalid rows
9222
+ leave a healthy session and sibling evaluations intact.
9223
+
9224
+ ### Availability and normalization
9225
+
9226
+ **Node on Windows, Linux and macOS with the selected ONNX Runtime; Android needs
9227
+ host adaptation.** GPU preference attempts actual advertised providers before
9228
+ CPU fallback; accepted configuration does not prove GPU node execution. Model
9229
+ selection, unchanged payloads, scoring interpretation and persistence remain
9230
+ application-owned. Complete lifecycle, errors and paths are documented in
9231
+ [native typed decisions](native-decisions.md).
9232
+
9233
+ ### Example
9234
+
9235
+ ```javascript
9236
+ import {createNativeDecisionModel} from 'arcane-os/local-ai/decisions';
9237
+
9238
+ function createMoonChefDecisions({onnx, paths}) {
9239
+ return createNativeDecisionModel({onnx, paths});
9240
+ }
9241
+ ```
9242
+
9243
+ The caller explicitly loads the returned model before evaluation and unloads
9244
+ or disposes it at its owning boundary; defining this function downloads nothing.
9245
+
9246
+ ## createNativeDecisionService()
9247
+
9248
+ ### Overview
9249
+
9250
+ Composes the same native decision model into an existing Core runtime without
9251
+ a renderer. The factory starts no inference, tokenizer or model preparation.
9252
+
9253
+ ### Signature and result
9254
+
9255
+ ```text
9256
+ createNativeDecisionService(configuration={}, {appRoot=process.cwd()}={})
9257
+ ```
9258
+
9259
+ Import from `arcane-os/core/decisions`. Configuration selects the model options
9260
+ above and an optional service `name` (default `decisions`); relative supplied
9261
+ `paths` resolve from `appRoot`. Explicit load obtains the registered local-AI
9262
+ and, when needed, model-assets owners through `context.getService`, then
9263
+ reacquires `getONNXRuntime()` after any recovery. Native members are `load`,
9264
+ `evaluate`, `classify`, `current`, `subscribe`, `unload`, `dispose` and Core
9265
+ `start(context)`.
9266
+
9267
+ RPC exposes `decisions.status`, `decisions.load`, `decisions.evaluate` and
9268
+ `decisions.unload`. Evaluation accepts `{rows,runOptions?}` and returns complete
9269
+ `{decisions,outputs}` using the existing tensor codec at the JSON boundary.
9270
+ `decisions.state` and replaying `subscribe(listener,{emitCurrent:true,signal})`
9271
+ report lifecycle. Unload is accepted service-lifetime cleanup; host shutdown
9272
+ still cancels request-lifetime load/evaluation.
9273
+
9274
+ ### Availability and normalization
9275
+
9276
+ **Node Core with an existing local-AI ONNX service and selected model files.**
9277
+ Registration does not wait for all services or open another host. Original
9278
+ inputs, complete outputs, failures and cleanup semantics match the native
9279
+ model. See [composition and example](native-decisions.md#compose-with-existing-core-services).
9280
+
9281
+ ### Example
9282
+
9283
+ ```javascript
9284
+ import {createNativeDecisionService} from 'arcane-os/core/decisions';
9285
+
9286
+ const decisions = createNativeDecisionService({
9287
+ model: 'onnx-community/laya-typed-decisions-ONNX',
9288
+ dtype: 'fp32',
9289
+ workingDirectory: '.models/laya'
9290
+ });
9291
+ // Add decisions to the application's existing Core services; load explicitly.
9292
+ ```
9293
+
9294
+ ## createNativeDecisionService default export
9295
+
9296
+ The default export from `arcane-os/core/decisions` is exactly the named
9297
+ `createNativeDecisionService` factory, with the same arguments and lifecycle.
9298
+
9109
9299
  ## createBrowserDecisionModel()
9110
9300
 
9111
9301
  ### Overview
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-os",
3
- "version": "0.67.0",
3
+ "version": "0.69.0",
4
4
  "description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",