arcane-os 0.95.0 → 0.97.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.
@@ -81,6 +81,10 @@ runtime layouts.
81
81
  | `arcane-os/ai/core-image` | Browser image lifecycle and complete PNG Blobs through an available Core service. |
82
82
  | `arcane-os/core/image` | Native image Core service with independent runtime preparation and retained model ownership. |
83
83
  | `arcane-os/core/speech` | Independent injected STT/TTS engine loading, request cancellation and joined Core service lifetime. |
84
+ | `arcane-os/local-ai/nemotron` | Retained native streaming recognition with complete timed words and optional diarization. |
85
+ | `arcane-os/local-ai/nemotron/build` | First-party ASR helper build against a prepared NeMo runtime. |
86
+ | `arcane-os/local-ai/magpie` | Retained native Magpie/NanoCodec synthesis with complete audio or ordered PCM. |
87
+ | `arcane-os/local-ai/magpie/build` | First-party TTS helper build against a prepared NeMo runtime. |
84
88
  | `arcane-os/local-ai/whisper` | Retained native Whisper model, complete recordings and joined helper lifetime. |
85
89
  | `arcane-os/local-ai/kokoro` | Retained native Kokoro synthesis using the existing ONNX/model-resource owners and a compiled phonemization/Opus helper. |
86
90
  | `arcane-os/local-ai/whisper/build` | First-party persistent helper build against selected installed Whisper headers and libraries. |
@@ -476,12 +480,26 @@ The remaining data-only subpaths are eight JSON Schemas and package metadata.
476
480
  | `KOKORO_REVISION` | constant | `arcane-os/local-ai/kokoro` | Core native speech | Selected upstream model revision |
477
481
  | `KOKORO_SAMPLE_RATE` | constant | `arcane-os/local-ai/kokoro` | Core native speech | Native PCM sample rate |
478
482
  | `KOKORO_VOICES` | constant | `arcane-os/local-ai/kokoro` | Core native speech | Complete 28-voice US/GB selection |
483
+ | `createNemotronRuntime()` | function | `arcane-os/local-ai/nemotron` | Core native speech | Node with a matching first-party helper, selected NeMo ASR runtime and models; Windows/Linux/macOS source, Android host adaptation |
484
+ | `NEMO_SPEECH_MODELS` | constant | `arcane-os/local-ai/nemotron` | Core native speech | Node; selected upstream model catalog, no acquisition at import |
485
+ | `prepareNemotronModels()` | function | `arcane-os/local-ai/nemotron` | Core native speech | Node with the shared model-assets service |
486
+ | `prepareMagpieModels()` | function | `arcane-os/local-ai/nemotron` | Core native speech | Node with the shared model-assets service |
487
+ | `createNemotronRuntime default export` | function | `arcane-os/local-ai/nemotron` | Core native speech | Same named function |
488
+ | `buildNemotronHelper()` | function | `arcane-os/local-ai/nemotron/build` | Core native speech | Node with CMake 3.26+, C++17 toolchain and platform-matching public NeMo ASR headers/libraries/CMake package |
489
+ | `buildNemotronHelper default export` | function | `arcane-os/local-ai/nemotron/build` | Core native speech | Same named function |
490
+ | `createMagpieRuntime()` | function | `arcane-os/local-ai/magpie` | Core native speech | Node with a matching first-party helper, selected NeMo TTS runtime, Magpie/tokenizer and NanoCodec assets; Windows/Linux/macOS source, Android host adaptation |
491
+ | `createMagpieRuntime default export` | function | `arcane-os/local-ai/magpie` | Core native speech | Same named function |
492
+ | `buildMagpieHelper()` | function | `arcane-os/local-ai/magpie/build` | Core native speech | Node with CMake 3.26+, C++17 toolchain, platform threads and matching public NeMo TTS headers/libraries/CMake package |
493
+ | `buildMagpieHelper default export` | function | `arcane-os/local-ai/magpie/build` | Core native speech | Same named function |
479
494
  | `createWhisperRuntime()` | function | `arcane-os/local-ai/whisper` | Core native speech | Node with a prepared matching helper, runtime, decoder and selected model |
480
495
  | `createWhisperRuntime default export` | function | `arcane-os/local-ai/whisper` | Core native speech | Same retained native engine factory |
481
496
  | `buildWhisperHelper()` | function | `arcane-os/local-ai/whisper/build` | Core native speech | Node with installed CMake/C++17 toolchain and matching Whisper source/runtime |
482
497
  | `buildWhisperOpenVinoRuntime()` | function | `arcane-os/local-ai/whisper/openvino-build` | Core native speech | Windows x64 Node with installed matching Whisper/OpenVINO sources and CMake/MSVC toolchain |
483
498
  | `createSpeechService default export` | function | `arcane-os/core/speech` | Core native speech | Same shared speech service factory |
484
499
  | `prepareCoreModelAssets()` | function | `arcane-os/ai/core-model-assets` | Core model assets | Browser with complete Blob/File members and available Core service |
500
+ | `discoverCoreModelAssets()` | function | `arcane-os/ai/core-model-assets` | Core model assets | Browser with an available model-assets Core service |
501
+ | `openExistingCoreModelAssets()` | function | `arcane-os/ai/core-model-assets` | Core model assets | Browser with an available model-assets Core service |
502
+ | `downloadCoreModelAssets()` | function | `arcane-os/ai/core-model-assets` | Core model assets | Browser with an available model-assets Core service |
485
503
  | `createModelAssetService()` | function | `arcane-os/core/model-assets` | Core model assets | Node Core with an application-selected working directory |
486
504
  | `createModelAssetService default export` | function | `arcane-os/core/model-assets` | Core model assets | Same native working-file service factory |
487
505
  | `createLocalAIService default export` | function | `arcane-os/core/local-ai` | Core local AI | Same native service factory |
@@ -7232,6 +7250,18 @@ no engine. The native routes of `AI.fetchTTS(payload, signal)` and
7232
7250
  `AI.fetchSTT(audio, signal)` forward their signals through these calls and
7233
7251
  normalize cancellation to `AbortError` with `ARCANE_AI_REQUEST_ABORTED`.
7234
7252
 
7253
+ `facade.speech.openStream(request,options)` returns
7254
+ `{streamId,ready,completion,current,push,forceEndpoint,finish,cancel}`.
7255
+ Ordered Float32 input retains the actual declared sample rate. Endpoint preserves
7256
+ stream/speaker scope and waits preceding updates; finish drains terminally.
7257
+ Do not await endpoint/finish/completion from their own update callback. Explicit
7258
+ cancel joins its native cleanup control, unlike ordinary signal cancellation.
7259
+ `synthesizeStream(request,{signal,onAudio,onProgress,onRequest})` awaits each
7260
+ complete ordered Uint8Array PCM contribution and its consumption acknowledgement,
7261
+ returns terminal metadata, and joins native cancellation. It plays no audio.
7262
+ Both streaming operations have no fixed timeout. Engine support/readiness remains
7263
+ independent from facade availability. See [streaming native speech](core-client.md#streaming-native-speech).
7264
+
7235
7265
  `facade.window.state({signal}?)` reads the calling document's native window;
7236
7266
  `facade.window.setState({state}, {signal}?)` selects `normal`, `maximized` or
7237
7267
  `fullscreen` for that same window. The matching Windows host returns
@@ -7899,7 +7929,12 @@ reports `ARCANE_NATIVE_RUN_UNSUPPORTED`.
7899
7929
 
7900
7930
  `build()` copies the complete selected app and dependency releases, the
7901
7931
  published SDK/runtime dependencies and the canonical Core entry/client into a
7902
- fresh output directory. Service factories are imported only when a real native
7932
+ temporary assembly, then publishes it at `<outputRoot>/<app-id>/`. Later
7933
+ successful builds replace only that app's generated output. Publication retains
7934
+ the previous output until the completion callback and cancellation boundary
7935
+ accept the replacement; failure restores it. Models and saved state belong in
7936
+ their separate persistent directories. See [stable output and recovery](core-native-packaging.md#output-and-host-contract).
7937
+ Service factories are imported only when a real native
7903
7938
  host later launches the generated Core entry, never during packaging.
7904
7939
 
7905
7940
  The generated `runtime/arcane-core.mjs` also accepts
@@ -8039,6 +8074,11 @@ the selected output root. There is no compiler or OS checkout requirement for
8039
8074
  application builds. The build machine needs its normal Node/npm toolchain and
8040
8075
  `tar`; execution needs Windows x64, .NET Framework 4.6.2 or later and WebView2.
8041
8076
 
8077
+ Successful builds publish the complete payload at `<outputRoot>/<app-id>/`,
8078
+ replacing that app's prior generated artifact through the same
8079
+ [joined publication lifecycle](core-native-packaging.md#output-and-host-contract).
8080
+ Runtime caches, models, saved profiles and unrelated outputs remain separate.
8081
+
8042
8082
  The matching Windows host consumes `appDescriptor.native.window` through
8043
8083
  `manifest.window`. Optional `width` and `height` select initial client dimensions
8044
8084
  in 96-DPI logical units; the host scales them for its actual DPI and fits the
@@ -8134,6 +8174,9 @@ asset is published or its Mac runtime has been executed.
8134
8174
 
8135
8175
  Build preserves the complete portable payload inside the bundle's Resources
8136
8176
  directory (`target.rootDir`) and returns its `.app` location as `bundleRoot`.
8177
+ The accepted bundle is `<outputRoot>/<app-id>.app/`; a later successful build
8178
+ replaces that bundle through the shared [publication lifecycle](core-native-packaging.md#output-and-host-contract),
8179
+ preserving separate saved state and model directories.
8137
8180
  The bundle supplies the SDK launcher and selected Node runtime. `verify()`
8138
8181
  reads assembled files; `run()` directly launches the bundled executable only on
8139
8182
  the matching Darwin architecture, observes diagnostics and waits for graceful
@@ -8297,8 +8340,9 @@ import createDiarizationService from 'arcane-os/core/diarization';
8297
8340
 
8298
8341
  ### Overview
8299
8342
 
8300
- Resolves one application's native state, workspace and optional shared endpoint
8301
- through the same public owner used by its packaged executable and external MCP.
8343
+ Resolves one application's native state, workspace and optional shared endpoint,
8344
+ plus a same-user shared model directory, through the same public owner used by
8345
+ its packaged executable and external MCP.
8302
8346
  This synchronous function performs no I/O, saved-state discovery, process start
8303
8347
  or migration.
8304
8348
 
@@ -8309,7 +8353,7 @@ resolveNativeLaunchContext({appId,context={}}={})
8309
8353
  ```
8310
8354
 
8311
8355
  Import from `arcane-os/core/host`. The result is a new complete context with
8312
- omitted fields filled. Windows defaults to `%LOCALAPPDATA%/Arcane/<appId>`
8356
+ omitted fields filled. `stateRoot` defaults on Windows to `%LOCALAPPDATA%/Arcane/<appId>`
8313
8357
  (home `AppData/Local` fallback), macOS to
8314
8358
  `~/Library/Application Support/Arcane/<appId>`, and portable Linux Node to
8315
8359
  absolute `$XDG_DATA_HOME/Arcane/<appId>` or `~/.local/share/Arcane/<appId>`.
@@ -8317,6 +8361,21 @@ Android and other adapted hosts provide their actual `stateRoot` and own native
8317
8361
  IPC/process adaptation.
8318
8362
 
8319
8363
  An omitted `workspaceRoot` becomes `<absolute selected stateRoot>/Workspace`.
8364
+ An omitted `modelsDirectory` uses the operating-system user's shared Arcane
8365
+ model directory: `%LOCALAPPDATA%/Arcane/Models` on Windows (home `AppData/Local`
8366
+ fallback), `~/Library/Application Support/Arcane/Models` on macOS, and absolute
8367
+ `$XDG_DATA_HOME/Arcane/Models` or `~/.local/share/Arcane/Models` on Linux. This
8368
+ default remains shared when the application explicitly selects another
8369
+ `stateRoot`; application state and workspace stay separate. Explicit
8370
+ `modelsDirectory` values remain unchanged. Other adapted hosts may supply a
8371
+ shared directory explicitly; their omitted value remains
8372
+ `<absolute selected stateRoot>/Models`.
8373
+
8374
+ This resolver supplies a location to its consumers; it neither changes every
8375
+ provider's store nor creates, moves or migrates model files. Services select
8376
+ that directory as the shared model-assets working directory, while applications
8377
+ may also discover their existing app-local originals. Model storage remains
8378
+ separate from replaceable native build output. See [persistent model locations](model-assets.md).
8320
8379
  Only a selected `sharedHost` object receives a default endpoint and log file:
8321
8380
  Windows uses a named pipe containing the URL-encoded complete absolute state
8322
8381
  path; Linux/macOS use `<absolute selected stateRoot>/core.sock`. The log is
@@ -8643,7 +8702,7 @@ separate states; prompts, models and application policy remain caller-owned.
8643
8702
  ### Signature and result
8644
8703
 
8645
8704
  ```text
8646
- createLocalAIService(configuration,{appRoot,runtimes=[],signal,onEvent,prepare,executionDevices}={})
8705
+ createLocalAIService(configuration,{appRoot,runtimes=[],signal,onEvent,prepare,executionDevices,autoStart=true}={})
8647
8706
  ```
8648
8707
 
8649
8708
  Import it from `arcane-os/core/local-ai`. `configuration` is the authored local-AI
@@ -8667,6 +8726,16 @@ asset services keep their own lifetimes. Pass only llama.cpp/Ollama/ONNX
8667
8726
  requirements to this factory; `createLocalImageService()` owns selected image
8668
8727
  requirements. The managed development and native entrypoints separate them.
8669
8728
 
8729
+ `autoStart:false` leaves these selected engines unprepared and unstarted during
8730
+ Core startup. Call `client.invoke('localai.prepare', {}, {signal})` when the
8731
+ application explicitly requests preparation. The operation invokes the
8732
+ configured `prepare` owner, emits its complete events as `localai.preparation`,
8733
+ starts configured engines and returns current state. Concurrent callers share
8734
+ in-flight preparation; completed preparation is reused. Engine/model readiness
8735
+ remains separate, so this result alone does not establish inference readiness.
8736
+ The default `autoStart:true` preserves startup preparation. No model is selected
8737
+ by this option.
8738
+
8670
8739
  The service provides `localai.status`, explicit `localai.services.recover`,
8671
8740
  `llama.status/models/load/unload/chat`, `onnx.status/load/run/unload`, and the documented native Ollama methods.
8672
8741
  `localai.state` reports runtime/model changes. `llama.status` and `llama.models`
@@ -8961,6 +9030,272 @@ US/GB voice identifiers. The engine uses `af_heart` when the caller omits
8961
9030
  `voice`; an explicit unsupported selection reports an error. Use this complete
8962
9031
  array to populate a native Kokoro voice selector.
8963
9032
 
9033
+ ## createNemotronRuntime()
9034
+
9035
+ ### Overview and syntax
9036
+
9037
+ Creates one retained native recognizer and optional diarizer without opening a
9038
+ microphone, loading a model or starting inference at construction.
9039
+
9040
+ ```javascript
9041
+ createNemotronRuntime({
9042
+ runtime, prepare, modelId = 'nemotron-3.5-asr-streaming-0.6b',
9043
+ modelPath, diarizationModelPath, modelAssets, assetProjectionId,
9044
+ resourcePaths, gpu, onEvent
9045
+ } = {})
9046
+ ```
9047
+
9048
+ Supply a prepared `runtime` or lazy `prepare({signal,onEvent})` descriptor
9049
+ with `helperExecutable` and selected native library paths. Select `gpu`
9050
+ explicitly (native ordinal, or `-1` for CPU). Model paths may come from the
9051
+ descriptor; omit the diarization path when speaker labels are not requested.
9052
+ Preparation, models and device selection remain caller-owned.
9053
+
9054
+ Alternatively supply the existing `modelAssets` service and a completed
9055
+ `assetProjectionId`, with `resourcePaths:{model,diarization?}` naming exact
9056
+ projection members. `load()` retains that projection before yielding and keeps
9057
+ it through actual helper cleanup; the caller can release preparation ownership
9058
+ after loading begins. Explicit load accepts these selection fields, and an
9059
+ active selection must be unloaded before replacement. Direct paths remain
9060
+ supported. See [shared catalog preparation](#preparenemotronmodels).
9061
+
9062
+ ### Returned members and lifetime
9063
+
9064
+ The engine exposes `current/subscribe/load/unload/transcribe/openStream/close`.
9065
+ Current state and replaying subscriptions report actual loaded readiness,
9066
+ native version, requested device, active speaker scope, error and reset state.
9067
+ `load` initializes the selection; `unload` and `close` join owned cleanup.
9068
+
9069
+ `openStream({sampleRate=16000,languageCode,model,onUpdate,signal})` resolves an
9070
+ owned `push/forceEndpoint/finish/cancel/completion/current` handle plus
9071
+ `sampleRate` and `speakerScope`. Feed mono `Float32Array` or
9072
+ `{encoding:'f32le',data:BASE64}` at the actual declared rate. The native sample
9073
+ rate contract accepts integer 8000–96000 or 0 for model rate. No encoded-media
9074
+ decoder is supplied. Updates preserve every alternative, text, word, timestamp,
9075
+ numeric speaker and final/provisional status.
9076
+
9077
+ `forceEndpoint` drains an utterance while retaining stream and speaker scope;
9078
+ `finish` terminally drains accepted input. Partial snapshots replace; finals
9079
+ remain separate recognition segments, never inferred conversational completion.
9080
+ `transcribe({audio,sampleRate,model?,languageCode?},options)` uses this same
9081
+ stream and returns complete `{text,words,results,speakerScope}`.
9082
+
9083
+ Cancellation joins native and callback cleanup. Terminating genuinely
9084
+ noninterruptible helper work exposes `resetRequired` and requires explicit
9085
+ reload; no engine restarts silently. Callbacks must return before joining their
9086
+ own stream/engine lifecycle, otherwise `NEMOTRON_CALLBACK_WAIT` is reported.
9087
+ Unsupported input reports `NEMOTRON_AUDIO_FORMAT_UNSUPPORTED`; native, callback
9088
+ and cleanup failures remain observable.
9089
+
9090
+ ### Availability and example
9091
+
9092
+ Node on Windows, Linux and macOS with the first-party helper and matching
9093
+ upstream NeMo ASR runtime/models; Android requires host adaptation. Selected
9094
+ Windows helper compilation is recorded in the [engine guide](native-nemotron.md);
9095
+ that is separate from inference, microphone or other-platform execution.
9096
+
9097
+ ```javascript
9098
+ import {createNemotronRuntime} from 'arcane-os/local-ai/nemotron';
9099
+
9100
+ function prepareDragonInterpreter(runtime, modelPath, gpu) {
9101
+ return createNemotronRuntime({runtime, modelPath, gpu});
9102
+ }
9103
+ // The native owner explicitly loads, supplies PCM and joins close.
9104
+ ```
9105
+
9106
+ See [native Nemotron](native-nemotron.md) for complete options, snapshots,
9107
+ callback rules and cancellation/reset outcomes.
9108
+
9109
+ ## createNemotronRuntime default export
9110
+
9111
+ The default export from `arcane-os/local-ai/nemotron` is the same
9112
+ `createNemotronRuntime` function, with identical inputs, results and lifetime.
9113
+
9114
+ ## `NEMO_SPEECH_MODELS`
9115
+
9116
+ Import this catalog from `arcane-os/local-ai/nemotron`. `stt` describes the
9117
+ selected Nemotron ASR and diarization GGUF companions; `tts` describes Magpie,
9118
+ NanoCodec and the matching ten tokenizer/configuration members. Each selection
9119
+ contains `modelId`, `providerId`, `name`, ordinary `members`, `resourcePaths`
9120
+ and optional `archives`. The upstream selections come from NVIDIA's
9121
+ NeMo-Speech.cpp 0.2.0 catalog. Importing the catalog performs no I/O and installs
9122
+ no runtime or model. See [the exact companion contract](native-speech.md#selected-nemo-model-acquisition).
9123
+
9124
+ ## prepareNemotronModels()
9125
+
9126
+ ```text
9127
+ prepareNemotronModels({modelAssets,workingDirectory,directories,id,signal,onProgress,refresh=false}={})
9128
+ ```
9129
+
9130
+ Import from `arcane-os/local-ai/nemotron`. Explicitly prepares the catalog's
9131
+ complete ASR and diarization selection through the existing model-assets
9132
+ service. Optional `directories` are searched first when `refresh` is false;
9133
+ the first complete matching catalog record is opened without downloading.
9134
+ Otherwise the shared `prepare` owner acquires the complete selection beneath
9135
+ `workingDirectory/model-assets/`. `refresh:true` requests a separate acquisition.
9136
+
9137
+ The promise resolves to `{assetProjectionId,directory,members,resourcePaths,release}`.
9138
+ An omitted `id` is generated. Ordered asynchronous `onProgress` receives full
9139
+ file-based semantic progress; existing selections report `reuse` then `ready`.
9140
+ Native acquisition additionally reports its shared resume, ownership-wait,
9141
+ activity and terminal states described under [`createModelAssetService()`](#createmodelassetservice).
9142
+ Completed members and saved partial transfers remain available for retry;
9143
+ HTTP continuation depends on the source response. Direct installed-directory
9144
+ reuse keeps its existing phase/file-count callback shape.
9145
+ Call the idempotent asynchronous `release()` to relinquish preparation ownership
9146
+ after the engine has retained it. Complete acquisitions and borrowed originals
9147
+ remain stored. Cancellation and callback failures join cleanup and preserve
9148
+ actual failures. The wrapper selects no device, installs no native runtime and
9149
+ starts no microphone or inference. See [native model acquisition](native-speech.md#selected-nemo-model-acquisition).
9150
+
9151
+ ## prepareMagpieModels()
9152
+
9153
+ ```text
9154
+ prepareMagpieModels({modelAssets,workingDirectory,directories,id,signal,onProgress,refresh=false}={})
9155
+ ```
9156
+
9157
+ Import from `arcane-os/local-ai/nemotron`. It has the same preparation,
9158
+ discovery, progress, cancellation and release contract as `prepareNemotronModels`,
9159
+ using the catalog's complete Magpie/NanoCodec/tokenizer selection. Its returned
9160
+ `resourcePaths` contains `model`, `codec` and `tokenizerConfig`. The shared TAR
9161
+ reader extracts the ten selected tokenizer members from the catalog's selected
9162
+ upstream archive ranges; offsets stay transport-local. Pass the completed
9163
+ projection to the existing Magpie engine. Voice, language and device selection
9164
+ remain caller-owned; preparation performs no synthesis.
9165
+
9166
+ ## buildNemotronHelper()
9167
+
9168
+ ### Overview and syntax
9169
+
9170
+ `buildNemotronHelper({runtime,outputRoot,signal,onEvent}={})` configures, builds
9171
+ and installs only the first-party Nemotron helper. `runtime.cmakeDirectory`
9172
+ selects an installed NeMo CMake package with its matching public ASR headers and
9173
+ libraries; `outputRoot` is the caller-owned output directory.
9174
+
9175
+ ### Result, availability and example
9176
+
9177
+ Returns `{platform,architecture,root,helperExecutable,executable,diagnostics}`;
9178
+ `executable` aliases `helperExecutable`, and diagnostics retains complete
9179
+ configure/compile/install results. Requires Node, CMake 3.26+, a C++17 compiler
9180
+ and matching platform runtime. It downloads no dependency or model and performs
9181
+ no inference. Cancellation and process failures remain observable.
9182
+
9183
+ ```javascript
9184
+ import {buildNemotronHelper} from 'arcane-os/local-ai/nemotron/build';
9185
+
9186
+ async function buildSelectedRecognizer(runtime, outputRoot, signal, onEvent) {
9187
+ return buildNemotronHelper({runtime, outputRoot, signal, onEvent});
9188
+ }
9189
+ ```
9190
+
9191
+ See [preparation and selection](native-nemotron.md#preparation-and-selection).
9192
+
9193
+ ## buildNemotronHelper default export
9194
+
9195
+ The default export from `arcane-os/local-ai/nemotron/build` is the same
9196
+ `buildNemotronHelper` function.
9197
+
9198
+ ## createMagpieRuntime()
9199
+
9200
+ ### Overview and syntax
9201
+
9202
+ Creates one retained native Magpie/NanoCodec synthesis owner. Construction
9203
+ downloads, loads and plays nothing.
9204
+
9205
+ ```javascript
9206
+ createMagpieRuntime({
9207
+ runtime, prepare, paths, modelAssets, assetProjectionId, resourcePaths,
9208
+ modelId = 'magpie', voice = 'Aria', languageCode = 'en-US',
9209
+ executionTarget, signal, onEvent
9210
+ } = {})
9211
+ ```
9212
+
9213
+ Supply a prepared executable/library descriptor or `prepare({signal})`.
9214
+ Select matching Magpie, NanoCodec and tokenizer `paths`, or an existing
9215
+ model-assets projection and `resourcePaths`. Explicit `executionTarget`
9216
+ selects CPU or CUDA with the host's visible device/UUID; no provider or device
9217
+ fallback is inferred. The tokenizer's own speaker map determines voice IDs.
9218
+
9219
+ ### Returned members and lifetime
9220
+
9221
+ The engine exposes `current/subscribe/load/unload/synthesize/synthesizeStream/stop/close`.
9222
+ State includes independent loaded readiness, active/queued requests, voice and
9223
+ language defaults, model-owned voices and streaming/format capability.
9224
+ `load` retains selected models; `unload` and `close` join owned work/assets.
9225
+
9226
+ Both synthesis methods accept exact `{input,model?,voice?,languageCode?,speed?}`;
9227
+ language is separate control information, and native speed must be 1.
9228
+ `synthesize(request,{signal,requestId,onProgress})` returns complete base64
9229
+ WAV (default) or PCM audio, MIME/format and speech metadata. Select
9230
+ `responseFormat:'pcm'` explicitly when needed.
9231
+ `synthesizeStream(request,{signal,requestId,onProgress,onAudio})` requires an
9232
+ awaited ordered `onAudio({pcm,format,sampleRate,channels,requestId})` callback.
9233
+ PCM is a Node Buffer of signed 16-bit little-endian samples; terminal metadata
9234
+ has `complete:true` without retaining the complete audio again. Playback
9235
+ belongs to the caller.
9236
+
9237
+ Requests retain FIFO ownership. `stop({requestId})` stops only that queued or
9238
+ active utterance and joins native/callback cleanup; cancellation rejects
9239
+ synthesis. In-flight native interruption is observed at a PCM callback boundary.
9240
+ A callback can abort its caller-owned signal and return; self-joining lifecycle
9241
+ calls reject `MAGPIE_CALLBACK_WAIT`. Complete native and cleanup errors remain
9242
+ observable. An interrupted request never returns fabricated complete audio.
9243
+
9244
+ ### Availability and example
9245
+
9246
+ Node on Windows, Linux and macOS with a matching helper, upstream NeMo TTS
9247
+ runtime and selected model assets; Android needs host adaptation. The
9248
+ [engine guide](native-magpie.md) separates selected Windows compilation from
9249
+ unverified inference, playback and other-platform execution.
9250
+
9251
+ ```javascript
9252
+ import {createMagpieRuntime} from 'arcane-os/local-ai/magpie';
9253
+
9254
+ function prepareDragonAnnouncer(runtime, paths, executionTarget) {
9255
+ return createMagpieRuntime({runtime, paths, executionTarget});
9256
+ }
9257
+ // The native owner loads explicitly; synthesis returns audio, not playback.
9258
+ ```
9259
+
9260
+ See [native Magpie](native-magpie.md) for complete selection, language, voices,
9261
+ callback constraints and request lifetime.
9262
+
9263
+ ## createMagpieRuntime default export
9264
+
9265
+ The default export from `arcane-os/local-ai/magpie` is the same
9266
+ `createMagpieRuntime` function, with identical inputs, results and lifetime.
9267
+
9268
+ ## buildMagpieHelper()
9269
+
9270
+ ### Overview and syntax
9271
+
9272
+ `buildMagpieHelper({runtime,outputRoot,signal,onEvent}={})` configures, builds
9273
+ and installs the first-party Magpie helper against the caller's installed
9274
+ `runtime.cmakeDirectory`, public NeMo TTS headers and matching libraries.
9275
+
9276
+ ### Result, availability and example
9277
+
9278
+ Returns `{platform,architecture,root,helperExecutable,diagnostics}`, preserving
9279
+ complete configure/compile/install results. Requires Node, CMake 3.26+, C++17,
9280
+ platform threads and matching NeMo libraries. `outputRoot` belongs to the
9281
+ caller. It downloads no dependency, model or voice and performs no inference.
9282
+ Cancellation and process failures remain observable.
9283
+
9284
+ ```javascript
9285
+ import {buildMagpieHelper} from 'arcane-os/local-ai/magpie/build';
9286
+
9287
+ async function buildSelectedAnnouncer(runtime, outputRoot, signal, onEvent) {
9288
+ return buildMagpieHelper({runtime, outputRoot, signal, onEvent});
9289
+ }
9290
+ ```
9291
+
9292
+ See [helper build prerequisites](native-magpie.md#build-the-first-party-helper).
9293
+
9294
+ ## buildMagpieHelper default export
9295
+
9296
+ The default export from `arcane-os/local-ai/magpie/build` is the same
9297
+ `buildMagpieHelper` function.
9298
+
8964
9299
  ## createWhisperRuntime()
8965
9300
 
8966
9301
  ### Overview
@@ -9091,7 +9426,7 @@ through `encoder: 'openvino-npu'`; they do not run this producer at startup.
9091
9426
 
9092
9427
  ### Overview and usage
9093
9428
 
9094
- `createSpeechService({stt,tts,signal}={})` from `arcane-os/core/speech` composes
9429
+ `createSpeechService({stt,tts,signal,autoLoad=true}={})` from `arcane-os/core/speech` composes
9095
9430
  independently selected STT and TTS engines as one Core service. Supply either
9096
9431
  role or both. Construction downloads, installs and loads nothing; the host
9097
9432
  owns engine creation, model/device selection and supported formats.
@@ -9114,6 +9449,18 @@ requests and results unchanged. Format decoding, model processing and encoding
9114
9449
  remain with that engine. This factory supplies no speech engine or automatic
9115
9450
  browser/native provider selection.
9116
9451
 
9452
+ Optional engine `openStream({...options,signal,onUpdate})` supplies continuous
9453
+ recognition; optional `synthesizeStream(request,{signal,onProgress,onAudio,requestId})`
9454
+ supplies awaited ordered PCM output. Each role reports `supportsStreaming`
9455
+ independently from loaded readiness. The Core streaming methods are
9456
+ `speech.open`, `push`, `endpoint`, `finish`, `cancel`, `synthesizeStream`,
9457
+ `audioConsumed` and `cancelSynthesis` (each under `speech.`). Request-scoped
9458
+ `speech.opened`, `speech.transcription` and `speech.audio` events retain stream
9459
+ ownership; TTS acknowledgements apply backpressure while control traffic continues.
9460
+ Endpoint drains an utterance without closing its stream; finish closes terminally.
9461
+ ASR finals are recognition segments, not conversational decisions. Cancellation
9462
+ joins the selected engine's native work. See the [complete streaming contract](native-speech.md#continuous-transcription-and-streaming-synthesis).
9463
+
9117
9464
  ### Members, results and events
9118
9465
 
9119
9466
  The returned object has `name: 'speech'`, `current`, `subscribe`, `close`,
@@ -9122,6 +9469,9 @@ The returned object has `name: 'speech'`, `current`, `subscribe`, `close`,
9122
9469
  - `start(context)` subscribes and starts both configured engine loads
9123
9470
  independently, returning immediately. Core and status remain responsive
9124
9471
  during loading; one role's failure leaves the other usable.
9472
+ With `autoLoad:false`, subscriptions and role capabilities remain available
9473
+ while startup requests no engine load. Explicit `speech.load` activates
9474
+ the selected role. The default preserves automatic startup loading.
9125
9475
  - `current()` and `methods['speech.status']()` return the same snapshot:
9126
9476
  `ready`, `transcriptionAvailable`, `synthesisAvailable`, `status`,
9127
9477
  `sttEngine`, `ttsEngine`, `roles.stt`, `roles.tts` and `closed`.
@@ -9170,10 +9520,12 @@ their operation with `SPEECH_ENGINE_UNAVAILABLE`; work after shutdown begins
9170
9520
  rejects with `CORE_CLOSING`. Engine errors remain observable, and engine cleanup
9171
9521
  failures reject shutdown with `AggregateError`. Asynchronous listener failures
9172
9522
  reach developer diagnostics. Engine platform support remains its own contract;
9173
- this Node composition layer adds no engine dependency. Existing AI readiness
9174
- consumers recognize `whisper.cpp` and `kokoro-onnx` IDs independently of the
9175
- service's engine-neutral interface. See the [complete engine and lifetime
9176
- contract](native-speech.md).
9523
+ this Node composition layer adds no engine dependency. The shared AI adapter
9524
+ follows the selected model and engine in per-role snapshots, including Nemotron
9525
+ and Magpie. Only its older aggregate-only fallback retains fixed
9526
+ `whisper.cpp`/`whisper-small` and `kokoro-onnx`/`kokoro` expectations.
9527
+ Unavailable streaming operations reject `SPEECH_OPERATION_UNAVAILABLE` without
9528
+ fallback. See the [complete engine and lifetime contract](native-speech.md).
9177
9529
 
9178
9530
  ## createSpeechService default export
9179
9531
 
@@ -9200,24 +9552,82 @@ engine. See [complete preparation and cleanup usage](model-assets.md).
9200
9552
 
9201
9553
  `createModelAssetService({appRoot=process.cwd()}={})` from
9202
9554
  `arcane-os/core/model-assets` returns the Core service for
9203
- `modelAssets.open/write/complete/release/status` and `modelAssets.state`.
9555
+ `modelAssets.open/write/complete/release/status`,
9556
+ `modelAssets.discover/openExisting/prepare/cancelPrepare`, and `modelAssets.state`.
9204
9557
  Relative working directories resolve from `appRoot`; explicit absolute
9205
9558
  directories remain caller-selected. Each projection has its own child
9206
9559
  directory and complete member files.
9207
9560
 
9208
9561
  `current()` returns `{closing,projections}`. `retain(id)` accepts a completed
9209
9562
  projection and returns `{id,directory,members,release}` for a native owner.
9210
- Native `prepare({id,workingDirectory,members,signal,onProgress,refresh=false})`
9211
- accepts ordered `{path,url}` members and returns their ready projection.
9563
+ Native `prepare({id,workingDirectory,members=[],archives=[],signal,onProgress,refresh=false})`
9564
+ accepts ordered `{path,url}` members and optional uncompressed TAR selections,
9565
+ returning their complete ready projection. An archive declares
9566
+ `{url,format:'tar',ranges?,members:[{path,member}]}`. Optional inclusive
9567
+ `{start,end,stopBefore?}` ranges use HTTP partial responses; the parser handles
9568
+ ordinary and PAX member paths and preserves each selected file completely.
9569
+ All declared companions must finish before readiness. Range framing stays
9570
+ transport-local.
9212
9571
  Complete native acquisitions persist beneath `workingDirectory/model-assets/`
9213
9572
  through unload, disposal and restart; ordinary calls reuse the exact complete
9214
9573
  ordered source selection without a network freshness check. Explicit
9215
9574
  `refresh:true` acquires a separate complete set without replacing active files.
9216
- Independent members transfer concurrently and progress reports phases and
9217
- completed files. Matching same-process preparations share acquisition with
9218
- independent callbacks and cancellation; the last interested cancellation joins
9219
- unfinished I/O and removes only that attempt. Separate processes may acquire
9220
- the same selection independently. Startup downloads nothing.
9575
+ Independent members transfer concurrently. Interrupted or cancelled acquisitions
9576
+ retain completed members and closed partial files for retry. A retry reuses the
9577
+ same recorded attempt and downloads only missing members. Ordinary-file HTTP
9578
+ continuation uses its retained strong ETag or Last-Modified validator with
9579
+ `Range` and `If-Range`; a matching `206` response appends. A full `200`, `416`,
9580
+ missing validator or prior encoded response restarts only that member and
9581
+ reports `restart`. One prior partial remains until its replacement completes.
9582
+ TAR selections replay the required segment framing while preserving already
9583
+ completed companions. HTTP framing remains internal to the transfer, not
9584
+ model identity or user-facing progress.
9585
+
9586
+ Matching same-process preparations share acquisition with independent callbacks
9587
+ and cancellation; cancelling one interested caller leaves the others running.
9588
+ The last interested cancellation joins I/O while retaining resumable data.
9589
+ Matching selections in separate processes coordinate their recorded transfer
9590
+ owner, report `waiting`, then reuse or resume after that owner releases or exits.
9591
+ Unrelated acquisitions remain concurrent. Member completion follows stream/file
9592
+ closure and promotion; whole-acquisition readiness follows all selected members.
9593
+ Startup downloads nothing, and retry remains an explicit preparation request.
9594
+
9595
+ Native acquisition progress is
9596
+ `{phase,state,message,completed,total,unit:'files',memberIndex?,path?,reason?,recovery?,error?,activity?}`.
9597
+ Phases are `open`, `download`, `reuse`, `resume`, `restart`, `complete`, `ready`,
9598
+ `waiting`, `heartbeat`, `stalled`, `interrupted`, `cancelled` and `failed`.
9599
+ States are `waiting`, `downloading`, `stalled`, `interrupted`, `cancelled`,
9600
+ `failed` and `ready`. A five-second heartbeat keeps active work observable;
9601
+ `stalled` means no source activity arrived for fifteen seconds, not a diagnosed
9602
+ outage. Waiting may include the other owner's observed `activity`. Plain
9603
+ `message` and `recovery` belong in ordinary status; complete `error` details
9604
+ remain diagnostic data. Progress uses phases and completed-file counts, not
9605
+ invented percentages. Terminal acquisition state does not imply that a
9606
+ cancelled subscriber receives callbacks after its cancellation boundary.
9607
+
9608
+ `discover({directories,catalog=[],recursive=true,signal})` reads only explicit
9609
+ installed directories and returns `{directories,models}`. Directory observations
9610
+ contain `{directory,exists,error?}`. Each model record has
9611
+ `{directory,entryPath,members:[{path,nativePath,available}],missingMembers,complete,source,catalogId?}`.
9612
+ The source is `directory`, `catalog` or `acquisition`. Split GGUF filename sets
9613
+ are one numerically ordered selection, including missing expected shards and
9614
+ the first shard as entry. This grouping also applies to completed acquisitions;
9615
+ all declared companions remain present. Ordinary readable symlinked files and
9616
+ directories are followed, with real-path cycle detection.
9617
+
9618
+ Catalog entries `{id,members,archives?,entryPath?}` declare exact companion sets.
9619
+ Acquisition-backed matching honors supplied source URLs and archive member
9620
+ names; path-only catalogs and ordinary directory discovery make no origin or
9621
+ runtime-readiness claim. No files are downloaded, loaded or moved by discovery.
9622
+
9623
+ `openExisting({id,directory,members:[{path}],signal})` opens a complete borrowed
9624
+ projection using those existing files. Missing members reject with
9625
+ `MODEL_ASSET_MEMBERS_MISSING` and the complete missing-member list. Release
9626
+ never deletes or copies borrowed originals. The three new operations also have
9627
+ matching Core RPC methods. Request-scoped `modelAssets.progress` carries
9628
+ `{id,progress}` with full file-based semantic progress; `cancelPrepare` aborts
9629
+ and joins actual acquisition cleanup. The browser helpers below preserve the
9630
+ request correlation and cancellation joins.
9221
9631
  `release(id)` relinquishes live preparation ownership. Native retains continue
9222
9632
  through actual engine release; completed native acquisitions remain stored.
9223
9633
  Browser `open/write/complete` projections retain their temporary lifetime and
@@ -9229,6 +9639,53 @@ handle only after its actual context/worker use ends. Original stored model
9229
9639
  files remain with their application owner. See
9230
9640
  [working-file service and wire operations](model-assets.md#native-ownership).
9231
9641
 
9642
+ ## discoverCoreModelAssets()
9643
+
9644
+ ```text
9645
+ discoverCoreModelAssets({client=getInstalledCoreClient(),directories,catalog,recursive,signal}={})
9646
+ ```
9647
+
9648
+ Import from `arcane-os/ai/core-model-assets`. Resolves the native `discover`
9649
+ result described above through the installed Core connection. Directories and
9650
+ catalog selections remain application-owned. Complete shard and companion
9651
+ availability is filesystem evidence, not a selected or loaded model. See
9652
+ [discovery records](model-assets.md).
9653
+
9654
+ ## openExistingCoreModelAssets()
9655
+
9656
+ ```text
9657
+ openExistingCoreModelAssets({client=getInstalledCoreClient(),directory,members,signal}={})
9658
+ ```
9659
+
9660
+ Import from `arcane-os/ai/core-model-assets`. Opens selected complete existing
9661
+ files through Core and returns `{id,directory,members,release}`. The helper
9662
+ generates its projection ID; `release()` is asynchronous and idempotent.
9663
+ Native engines retain their own use; borrowed original files remain intact.
9664
+ Cancellation joins uncancelled cleanup before rejecting.
9665
+
9666
+ ## downloadCoreModelAssets()
9667
+
9668
+ ```text
9669
+ downloadCoreModelAssets({client=getInstalledCoreClient(),workingDirectory,members,archives,refresh=false,signal,onProgress}={})
9670
+ ```
9671
+
9672
+ Import from `arcane-os/ai/core-model-assets`. Explicitly invokes native
9673
+ acquisition for complete ordinary and optional TAR-selected members and returns
9674
+ `{id,directory,members,release}`. It generates the ID, observes only that request's
9675
+ complete progress, and awaits asynchronous callbacks in order. Cancellation or
9676
+ a callback failure joins native `cancelPrepare` cleanup and local callback
9677
+ delivery before settlement; actual cleanup failures remain observable.
9678
+ When Core rejects preparation, the helper first delivers already queued
9679
+ terminal progress before its internal cleanup cancellation and rejection.
9680
+ Explicit caller cancellation retains its no-late-callback boundary.
9681
+ Release relinquishes preparation ownership while completed downloads remain
9682
+ stored. Interrupted/cancelled native transfers retain completed members and
9683
+ saved partials for an explicit retry; the shared owner's HTTP continuation and
9684
+ member-restart rules apply. Progress forwards its full ownership-wait,
9685
+ heartbeat/stall and terminal records without inventing completion. No model,
9686
+ runtime or device is selected implicitly. See
9687
+ [download and progress usage](model-assets.md).
9688
+
9232
9689
  ## createModelAssetService default export
9233
9690
 
9234
9691
  The default export from `arcane-os/core/model-assets` is the same