arcane-os 0.62.0 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +1 -1
- package/browser-runtime/core/client.mjs +7 -2
- package/docs/reference/README.md +7 -0
- package/docs/reference/cli.md +5 -1
- package/docs/reference/core-client.md +11 -2
- package/docs/reference/core-native-packaging.md +57 -8
- package/docs/reference/core-repositories.md +149 -0
- package/docs/reference/inventory/package-api.json +163 -9
- package/docs/reference/local-ai.md +51 -7
- package/docs/reference/local-image-flux.md +154 -0
- package/docs/reference/local-image-generation.md +12 -0
- package/docs/reference/local-image-sdxl.md +139 -0
- package/docs/reference/local-whisper.md +219 -0
- package/docs/reference/native-speech.md +163 -0
- package/docs/reference/runtime-modules.md +16 -2
- package/docs/reference/sdk-api.md +335 -6
- package/package.json +5 -1
- package/runtime/arcane/components/speech.html +15 -3
- package/runtime/arcane/components/voice-transcription.html +19 -3
- package/runtime/arcane/modules/AI.js +250 -27
- package/runtime/arcane/modules/AIProviderRuntime.js +20 -3
- package/runtime/arcane/modules/AIRuntimeState.js +15 -2
- package/runtime/arcane/modules/ComponentContracts.js +3 -0
- package/schemas/arcane-app.schema.json +53 -2
- package/schemas/arcane-package.schema.json +53 -2
- package/src/core/repositories.mjs +210 -0
- package/src/core/services/speech.mjs +361 -0
- package/src/local-ai/config.mjs +9 -3
- package/src/local-ai/dev.mjs +32 -2
- package/src/local-ai/image-library.mjs +9 -0
- package/src/local-ai/image-models/flux.mjs +31 -0
- package/src/local-ai/image-models/sdxl.mjs +18 -0
- package/src/local-ai/install.mjs +26 -7
- package/src/local-ai/whisper/build.mjs +48 -0
- package/src/local-ai/whisper/config.mjs +61 -0
- package/src/local-ai/whisper/index.mjs +515 -0
- package/src/local-ai/whisper/install.mjs +274 -0
- package/src/local-ai/whisper/native/CMakeLists.txt +98 -0
- package/src/local-ai/whisper/native/NOTICE +18 -0
- package/src/local-ai/whisper/native/README.md +104 -0
- package/src/local-ai/whisper/native/main.cpp +489 -0
- package/src/native/portable-layout.mjs +37 -7
- package/src/native/windows-provider.mjs +39 -15
|
@@ -57,15 +57,22 @@ runtime layouts.
|
|
|
57
57
|
| `arcane-os/core/runtime` | App-neutral native Core dispatcher and service lifecycle. |
|
|
58
58
|
| `arcane-os/core/stdio` | Framed Node stdio transport with graceful runtime drain. |
|
|
59
59
|
| `arcane-os/core/host` | Node-only reusable Core host lifecycle with explicitly supplied services. |
|
|
60
|
+
| `arcane-os/core/repositories` | Native persistent ArcaneData paths and explicitly selected connected working repositories. |
|
|
60
61
|
| `arcane-os/core/packaged-web` | Core-owned packaged web listener with a persisted loopback origin and ready/failure events. |
|
|
61
62
|
| `arcane-os/core/preferences` | Existing preference RPC methods with an application-selected file, ordered writes and owned drain. |
|
|
62
63
|
| `arcane-os/core/diarization` | Lazy native speaker-diarization service, explicit stream methods and lifecycle/result events. |
|
|
63
64
|
| `arcane-os/diarization` | Retained Nemotron model helper and independent caller-fed audio streams. |
|
|
64
65
|
| `arcane-os/diarization/build` | First-party helper compilation against explicitly installed NeMo-Speech.cpp libraries. |
|
|
65
66
|
| `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). |
|
|
66
|
-
| `arcane-os/local-ai` | Official runtime installation and native artifact bundling for selected llama.cpp/Ollama/ONNX requirements and NeMo libraries. |
|
|
67
|
+
| `arcane-os/local-ai` | Official runtime installation and native artifact bundling for selected llama.cpp/Ollama/ONNX/image requirements and NeMo libraries. |
|
|
67
68
|
| `arcane-os/local-ai/onnx` | Retained native ONNX worker sessions with explicit graph loading and complete tensor inference. |
|
|
68
69
|
| `arcane-os/ai/core-onnx` | Optional browser access to system ONNX through an existing Core connection. |
|
|
70
|
+
| `arcane-os/local-ai/image` | Retained native stable-diffusion.cpp context, complete PNG generation and owned worker lifetime. |
|
|
71
|
+
| `arcane-os/ai/core-image` | Browser image lifecycle and complete PNG Blobs through an available Core service. |
|
|
72
|
+
| `arcane-os/core/image` | Native image Core service with independent runtime preparation and retained model ownership. |
|
|
73
|
+
| `arcane-os/core/speech` | Independent injected STT/TTS engine loading, request cancellation and joined Core service lifetime. |
|
|
74
|
+
| `arcane-os/ai/core-model-assets` | Complete stored browser model members projected through Core into native working files. |
|
|
75
|
+
| `arcane-os/core/model-assets` | Native working-file preparation, engine retain handles and joined cleanup. |
|
|
69
76
|
| `arcane-os/integrated-provider` | Fixed integrated shared-development provider. |
|
|
70
77
|
| `arcane-os/packager` | Low-level browser app packager. |
|
|
71
78
|
| `arcane-os/release-bundle` | Deterministic external release bundles. |
|
|
@@ -386,6 +393,8 @@ The remaining data-only subpaths are eight JSON Schemas and package metadata.
|
|
|
386
393
|
| `arcaneNativeBuilderProvider default export` | singleton | `arcane-os/native/portable-provider` | Portable native provider | Node; produces a portable payload rather than an executable host |
|
|
387
394
|
| `startCoreHost()` | function | `arcane-os/core/host` | Native Core host composition | Node with readable input and writable output streams |
|
|
388
395
|
| `readCoreLaunchContext()` | function | `arcane-os/core/host` | Native Core host composition | Node; reads explicitly selected launch JSON |
|
|
396
|
+
| `resolveArcaneDataPaths()` | function | `arcane-os/core/repositories` | Native repository workspaces | Node on Windows, Linux and macOS; Android supplies its data root |
|
|
397
|
+
| `createRepositoryWorkspace()` | function | `arcane-os/core/repositories` | Native repository workspaces | Node with Git; Android requires host process adaptation |
|
|
389
398
|
| `createWindowsNativeProvider()` | function | `arcane-os/native/windows-provider` | Windows native provider | Node assembly; Windows x64/WebView2 execution |
|
|
390
399
|
| `arcaneNativeBuilderProvider` | singleton | `arcane-os/native/windows-provider` | Windows native provider | Node assembly; Windows x64/WebView2 execution |
|
|
391
400
|
| `arcaneNativeBuilderProvider default export` | singleton | `arcane-os/native/windows-provider` | Windows native provider | Node assembly; Windows x64/WebView2 execution |
|
|
@@ -403,6 +412,15 @@ The remaining data-only subpaths are eight JSON Schemas and package metadata.
|
|
|
403
412
|
| `createLocalAIService()` | function | `arcane-os/core/local-ai` | Core local AI | Node with selected llama.cpp/Ollama/ONNX runtimes |
|
|
404
413
|
| `createONNXRuntime()` | function | `arcane-os/local-ai/onnx` | Core local AI | Node with prepared Microsoft ONNX runtime |
|
|
405
414
|
| `createCoreONNXRuntime()` | function | `arcane-os/ai/core-onnx` | Core local AI | Browser with an available Core ONNX service |
|
|
415
|
+
| `createImageRuntime()` | function | `arcane-os/local-ai/image` | Core local images | Node with a prepared native image runtime and caller-selected model |
|
|
416
|
+
| `createCoreImageRuntime()` | function | `arcane-os/ai/core-image` | Core local images | Browser with an available Core image service |
|
|
417
|
+
| `createLocalImageService()` | function | `arcane-os/core/image` | Core local images | Node Core with selected stable-diffusion.cpp requirements |
|
|
418
|
+
| `createLocalImageService default export` | function | `arcane-os/core/image` | Core local images | Same native image service factory |
|
|
419
|
+
| `createSpeechService()` | function | `arcane-os/core/speech` | Core native speech | Node Core with explicitly supplied speech engines |
|
|
420
|
+
| `createSpeechService default export` | function | `arcane-os/core/speech` | Core native speech | Same shared speech service factory |
|
|
421
|
+
| `prepareCoreModelAssets()` | function | `arcane-os/ai/core-model-assets` | Core model assets | Browser with complete Blob/File members and available Core service |
|
|
422
|
+
| `createModelAssetService()` | function | `arcane-os/core/model-assets` | Core model assets | Node Core with an application-selected working directory |
|
|
423
|
+
| `createModelAssetService default export` | function | `arcane-os/core/model-assets` | Core model assets | Same native working-file service factory |
|
|
406
424
|
| `createLocalAIService default export` | function | `arcane-os/core/local-ai` | Core local AI | Same native service factory |
|
|
407
425
|
| `ensureLocalAIRuntimes()` | function | `arcane-os/local-ai` | Core local AI | Node; selected upstream platform assets |
|
|
408
426
|
| `bundleLocalAIRuntimes()` | function | `arcane-os/local-ai` | Core local AI | Node; complete native runtime assembly |
|
|
@@ -7409,12 +7427,23 @@ application builds. The build machine needs its normal Node/npm toolchain and
|
|
|
7409
7427
|
The returned `arcane-native-builder/1` provider exposes `describe`, `doctor`,
|
|
7410
7428
|
`prepare`, `build`, `verify` and `run`. Build returns `{app,target,manifest}`
|
|
7411
7429
|
with the actual directory at `target.rootDir`. Verification reads the artifact;
|
|
7412
|
-
it does not launch the window. Run launches
|
|
7413
|
-
|
|
7430
|
+
it does not launch the window. Run launches the executable recorded in the
|
|
7431
|
+
saved `manifest.host.executable` and observes complete diagnostics and exit.
|
|
7432
|
+
Cancellation closes input and waits for host-owned drain,
|
|
7414
7433
|
including accepted service work, without a forced termination deadline. Missing
|
|
7415
7434
|
prerequisites, download/extraction failures and host failures remain observable
|
|
7416
7435
|
through the operation's error/event boundary.
|
|
7417
7436
|
|
|
7437
|
+
Assembly names the launcher from `appDescriptor.displayName` plus `.exe`,
|
|
7438
|
+
with a matching `.exe.config` file. Low-level compositions without a nonempty
|
|
7439
|
+
string display name use the app ID. Windows-reserved filename characters and
|
|
7440
|
+
control characters become underscores; reserved DOS device basenames receive
|
|
7441
|
+
an underscore prefix. Supported Unicode, spaces and case remain, as do the
|
|
7442
|
+
original descriptor and title. Icon embedding, file inventory, verification
|
|
7443
|
+
and run use this same name. Existing artifacts retain the executable recorded
|
|
7444
|
+
in their manifest; the reusable downloaded host retains `Arcane.exe` and
|
|
7445
|
+
`Arcane.exe.config`, and `runtime/ArcaneCore.exe` remains unchanged.
|
|
7446
|
+
|
|
7418
7447
|
During assembly, `appDescriptor.native.icon` selects the app's existing image.
|
|
7419
7448
|
PNG and ICO inputs produce a derived `runtime/arcane-app.ico` and update only
|
|
7420
7449
|
the copied application's executable icon. Source assets, the selected host
|
|
@@ -7664,6 +7693,63 @@ separate argument; other composing hosts may use the same seam. This JavaScript
|
|
|
7664
7693
|
contract does not establish a compiled host or matching release archive. See
|
|
7665
7694
|
[launch-time locations](core-native-packaging.md#launch-time-locations).
|
|
7666
7695
|
|
|
7696
|
+
## resolveArcaneDataPaths()
|
|
7697
|
+
|
|
7698
|
+
### Overview
|
|
7699
|
+
|
|
7700
|
+
Resolves the native per-user `ArcaneData` directory and its `Repos` child without
|
|
7701
|
+
creating directories or changing application state.
|
|
7702
|
+
|
|
7703
|
+
### Signature and result
|
|
7704
|
+
|
|
7705
|
+
```text
|
|
7706
|
+
resolveArcaneDataPaths({dataRoot}={})
|
|
7707
|
+
```
|
|
7708
|
+
|
|
7709
|
+
Returns absolute `{dataRoot,repositoriesRoot}`. Defaults use Windows LocalAppData,
|
|
7710
|
+
Linux XDG data home or `~/.local/share`, and macOS user Application Support.
|
|
7711
|
+
Android and other adapted hosts supply their persistent `dataRoot`. An explicit
|
|
7712
|
+
root is used directly, with relative paths resolved from the process working
|
|
7713
|
+
directory. See [native repository locations](core-repositories.md#persistent-locations).
|
|
7714
|
+
|
|
7715
|
+
```javascript
|
|
7716
|
+
import {resolveArcaneDataPaths} from 'arcane-os/core/repositories';
|
|
7717
|
+
|
|
7718
|
+
const {repositoriesRoot} = resolveArcaneDataPaths();
|
|
7719
|
+
```
|
|
7720
|
+
|
|
7721
|
+
## createRepositoryWorkspace()
|
|
7722
|
+
|
|
7723
|
+
### Overview
|
|
7724
|
+
|
|
7725
|
+
Owns one native connected working checkout under `ArcaneData/Repos/<name>` or an
|
|
7726
|
+
explicit existing path. The application owns the remote, branch and Core API.
|
|
7727
|
+
|
|
7728
|
+
### Signature and result
|
|
7729
|
+
|
|
7730
|
+
```text
|
|
7731
|
+
createRepositoryWorkspace({name,directory,dataRoot,remote,branch,onEvent,run=runProcess}={})
|
|
7732
|
+
```
|
|
7733
|
+
|
|
7734
|
+
Returns `{directory,open,status,pull,push,close,drain,dispose}`. Construction does
|
|
7735
|
+
no I/O. Operations accept `{signal}`; a missing or empty destination clones once,
|
|
7736
|
+
while existing checkout files, branches, remotes and local changes remain intact.
|
|
7737
|
+
Same-directory calls are ordered within the process. Shutdown drains accepted
|
|
7738
|
+
work and preserves the checkout. No CLI cwd, launch state, preference, snapshot
|
|
7739
|
+
cache or existing user-data location changes. See the [complete inputs, results,
|
|
7740
|
+
errors and lifecycle](core-repositories.md#one-connected-working-checkout).
|
|
7741
|
+
|
|
7742
|
+
```javascript
|
|
7743
|
+
import {createRepositoryWorkspace} from 'arcane-os/core/repositories';
|
|
7744
|
+
|
|
7745
|
+
const repository = createRepositoryWorkspace({
|
|
7746
|
+
name: 'moon-cheese-dispatches',
|
|
7747
|
+
remote: applicationConnection.remote
|
|
7748
|
+
});
|
|
7749
|
+
await repository.open({signal});
|
|
7750
|
+
await repository.close();
|
|
7751
|
+
```
|
|
7752
|
+
|
|
7667
7753
|
## createCoreLocalAIProvider()
|
|
7668
7754
|
|
|
7669
7755
|
### Overview
|
|
@@ -7708,7 +7794,7 @@ separate states; prompts, models and application policy remain caller-owned.
|
|
|
7708
7794
|
### Signature and result
|
|
7709
7795
|
|
|
7710
7796
|
```text
|
|
7711
|
-
createLocalAIService(configuration,{appRoot,runtimes=[],signal,onEvent}={})
|
|
7797
|
+
createLocalAIService(configuration,{appRoot,runtimes=[],signal,onEvent,prepare}={})
|
|
7712
7798
|
```
|
|
7713
7799
|
|
|
7714
7800
|
Import it from `arcane-os/core/local-ai`. `configuration` is the authored local-AI
|
|
@@ -7718,6 +7804,13 @@ resolved installed runtime records. It returns a Core service definition with
|
|
|
7718
7804
|
existing Core lifecycle. Shutdown cancels owned work and joins owned processes;
|
|
7719
7805
|
an already running external service remains under its external owner.
|
|
7720
7806
|
|
|
7807
|
+
Optional `prepare({signal,onEvent})` supplies resolved runtime records during
|
|
7808
|
+
this service's startup. Only operations depending on that service wait for its
|
|
7809
|
+
preparation; the development listener and independently composed image/model
|
|
7810
|
+
asset services keep their own lifetimes. Pass only llama.cpp/Ollama/ONNX
|
|
7811
|
+
requirements to this factory; `createLocalImageService()` owns selected image
|
|
7812
|
+
requirements. The managed development and native entrypoints separate them.
|
|
7813
|
+
|
|
7721
7814
|
The service provides `localai.status`, explicit `localai.services.recover`,
|
|
7722
7815
|
`llama.status/models/load/unload/chat`, `onnx.status/load/run/unload`, and the documented native Ollama methods.
|
|
7723
7816
|
`localai.state` reports runtime/model changes. `llama.chunk` and `ollama.chunk`
|
|
@@ -7761,6 +7854,231 @@ accessor's requests and subscriptions; unloading shared models is explicit.
|
|
|
7761
7854
|
Construction installs no runtime and opens no transport. Existing browser
|
|
7762
7855
|
ONNX/Wllama remain independent. See [Core and browser usage](local-ai.md#onnx-through-core-and-the-browser).
|
|
7763
7856
|
|
|
7857
|
+
## createImageRuntime()
|
|
7858
|
+
|
|
7859
|
+
`createImageRuntime({libraryPath,bindingModulePath,variants=[],models=[],backend='auto',signal?,onEvent?})`
|
|
7860
|
+
from `arcane-os/local-ai/image` retains the native image owner for the selected
|
|
7861
|
+
library. Prepare the installed record through `ensureLocalAIRuntimes()` and
|
|
7862
|
+
supply complete model descriptors with actual native resource paths. The
|
|
7863
|
+
factory installs no software and starts its worker when an operation needs it.
|
|
7864
|
+
|
|
7865
|
+
It returns `load({model,context?,signal?})`, `generate({model,prompt,parameters?,
|
|
7866
|
+
signal?,onProgress?})`, `edit({model,image,prompt,strength,parameters?,signal?,onProgress?})`,
|
|
7867
|
+
`unload({signal?})`, `current()`,
|
|
7868
|
+
`subscribe(listener,{replay=true})` and asynchronous `close()`. A model ID uses
|
|
7869
|
+
its supplied descriptor; a complete descriptor may be passed directly.
|
|
7870
|
+
Generation returns all PNG results as `images: [{data,mediaType,width,height}]`
|
|
7871
|
+
with native result metadata. Prompts and parameters remain complete.
|
|
7872
|
+
|
|
7873
|
+
`edit()` accepts the original complete PNG as `image: {data: Uint8Array,
|
|
7874
|
+
mediaType}` and copies the supplied view at acceptance. Its explicit finite
|
|
7875
|
+
`strength` is from `0` through `1`, takes precedence over model/parameter
|
|
7876
|
+
defaults and is never clamped. It decodes in the existing worker and uses the
|
|
7877
|
+
same selected context, queue, progress, cancellation and complete result
|
|
7878
|
+
contract. SD1.4 advertises `txt2img` and `img2img`. See the
|
|
7879
|
+
[editing contract](local-image-editing.md#core-and-native-request) for supported
|
|
7880
|
+
PNG input, native preprocessing, alpha and strength-zero semantics; the
|
|
7881
|
+
original file remains unchanged.
|
|
7882
|
+
|
|
7883
|
+
Accessors for the same library share its worker and selected context. Competing
|
|
7884
|
+
native operations are ordered at that owner; unrelated services remain
|
|
7885
|
+
concurrent. State observation replays synchronously by default. Cancellation
|
|
7886
|
+
joins the owning native operation; a model constructor may finish before its
|
|
7887
|
+
new context can be released. Native accessor `close()` cancels its requests,
|
|
7888
|
+
joins them and releases the shared selected context before its working files
|
|
7889
|
+
can be retired. The final reference closes the worker. This differs from the
|
|
7890
|
+
browser accessor's detach-only ownership below. See the
|
|
7891
|
+
[image lifecycle, backend and error contract](local-image-generation.md).
|
|
7892
|
+
|
|
7893
|
+
## createCoreImageRuntime()
|
|
7894
|
+
|
|
7895
|
+
`createCoreImageRuntime({client=getInstalledCoreClient(),signal?,onEvent?})`
|
|
7896
|
+
from `arcane-os/ai/core-image` returns immediately with `load`, `generate`, `edit`,
|
|
7897
|
+
`unload`, `inspect`, `current`, `subscribe` and `close`. It subscribes before
|
|
7898
|
+
requesting an initial status snapshot so newer lifecycle events win. It opens
|
|
7899
|
+
no connection and installs or selects no model.
|
|
7900
|
+
|
|
7901
|
+
`load({model,context?,assetProjectionId?,resourcePaths?,signal?})` and
|
|
7902
|
+
`generate({model,prompt,parameters?,assetProjectionId?,resourcePaths?,signal?,
|
|
7903
|
+
onProgress?})` use the selected Core service. Generation acknowledges with
|
|
7904
|
+
transient `Thinking` synchronously and returns complete
|
|
7905
|
+
`images: [{blob,mediaType,width,height}]` plus native result metadata.
|
|
7906
|
+
`unload({signal?})` explicitly releases the shared selected model;
|
|
7907
|
+
`inspect({signal?})` reads authoritative state without waiting for preparation.
|
|
7908
|
+
All request methods use `timeoutMs:0`. `current()` includes transient requests,
|
|
7909
|
+
status, busy and closed state; no prompt or image history is saved.
|
|
7910
|
+
|
|
7911
|
+
`edit({model,image,prompt,strength,parameters?,assetProjectionId?,resourcePaths?,
|
|
7912
|
+
signal?,onProgress?})` accepts the original PNG Blob or File and returns the
|
|
7913
|
+
same complete Blob result shape. It publishes `Thinking` before reading that
|
|
7914
|
+
input, preserves its complete encoded content through Core, and performs no
|
|
7915
|
+
browser drawing, re-encoding, resizing or saving. The request signal covers
|
|
7916
|
+
input preparation and native cancellation; an in-flight `Blob.arrayBuffer()`
|
|
7917
|
+
finishes before cancellation can be observed. No aborted result or late
|
|
7918
|
+
progress reaches the caller. See [full editing usage and format limits](local-image-editing.md).
|
|
7919
|
+
|
|
7920
|
+
`subscribe(listener,{replay=true,signal?})` returns an unsubscribe function.
|
|
7921
|
+
`close()` cancels and joins only this accessor's requests and subscriptions,
|
|
7922
|
+
leaving the shared Core client and selected model with their owners. Request
|
|
7923
|
+
errors retain complete details; an unavailable Core reports
|
|
7924
|
+
`ARCANE_IMAGE_CORE_UNAVAILABLE`. Aborted operations deliver no late result or
|
|
7925
|
+
progress. See the [complete browser example and events](local-image-generation.md#browser-accessor).
|
|
7926
|
+
|
|
7927
|
+
## createLocalImageService()
|
|
7928
|
+
|
|
7929
|
+
`createLocalImageService(configuration,{appRoot,runtimes=[],signal?,onEvent?,prepare?,modelAssets?})`
|
|
7930
|
+
from `arcane-os/core/image` returns a Core service with `current()`, replaying
|
|
7931
|
+
`subscribe(listener)`, native preparation, request methods and joined disposal.
|
|
7932
|
+
`configuration` is the selected `localAI` record. Optional
|
|
7933
|
+
`prepare({appRoot,configuration,requirement,signal,onEvent})` returns one
|
|
7934
|
+
installed image-runtime record. Startup retains this preparation in the
|
|
7935
|
+
background; `image.status` and unrelated services remain responsive.
|
|
7936
|
+
|
|
7937
|
+
The service owns `image.status/load/generate/edit/unload` and
|
|
7938
|
+
`image.state/progress`. Pass the same `createModelAssetService()` instance that
|
|
7939
|
+
Core exposes when using `assetProjectionId` and `resourcePaths`. It retains
|
|
7940
|
+
prepared model files through actual native completion, replacement, unload and
|
|
7941
|
+
shutdown. PNG base64 is transport-only framing; the complete result is decoded
|
|
7942
|
+
by the browser accessor. See [parameters, results and ownership](local-image-generation.md#core-service-and-transport).
|
|
7943
|
+
|
|
7944
|
+
`image.edit` takes `{model,image,prompt,strength,parameters?,streamId?,
|
|
7945
|
+
assetProjectionId?,resourcePaths?}`. Only the Core JSON boundary encodes the
|
|
7946
|
+
input as `{data: completeBase64PNG,encoding:'base64',mediaType}`. The service
|
|
7947
|
+
acknowledges accepted work through `image.progress`, preserves the original
|
|
7948
|
+
prompt and complete image, and retains existing model-assets ownership through
|
|
7949
|
+
native completion. Its complete encoded PNG result has the same shape as
|
|
7950
|
+
`image.generate`; [editing semantics](local-image-editing.md) remain with the
|
|
7951
|
+
selected model and native engine.
|
|
7952
|
+
|
|
7953
|
+
## createLocalImageService default export
|
|
7954
|
+
|
|
7955
|
+
The default export from `arcane-os/core/image` is the same
|
|
7956
|
+
`createLocalImageService` factory and lifecycle described above.
|
|
7957
|
+
|
|
7958
|
+
## createSpeechService()
|
|
7959
|
+
|
|
7960
|
+
### Overview and usage
|
|
7961
|
+
|
|
7962
|
+
`createSpeechService({stt,tts,signal}={})` from `arcane-os/core/speech` composes
|
|
7963
|
+
independently selected STT and TTS engines as one Core service. Supply either
|
|
7964
|
+
role or both. Construction downloads, installs and loads nothing; the host
|
|
7965
|
+
owns engine creation, model/device selection and supported formats.
|
|
7966
|
+
|
|
7967
|
+
```javascript
|
|
7968
|
+
import {createCoreRuntime} from 'arcane-os/core/runtime';
|
|
7969
|
+
import {createSpeechService} from 'arcane-os/core/speech';
|
|
7970
|
+
|
|
7971
|
+
// transcriptionEngine is the host's already constructed, selected engine.
|
|
7972
|
+
const speech = createSpeechService({stt: transcriptionEngine});
|
|
7973
|
+
const core = createCoreRuntime({services: [speech]});
|
|
7974
|
+
core.start();
|
|
7975
|
+
```
|
|
7976
|
+
|
|
7977
|
+
Each supplied engine exposes `current()`, replaying `subscribe(listener)`,
|
|
7978
|
+
`load({signal})`, `close()` and its role's
|
|
7979
|
+
`transcribe(request,{signal,onProgress})` or
|
|
7980
|
+
`synthesize(request,{signal,onProgress})`. The service forwards complete
|
|
7981
|
+
requests and results unchanged. Format decoding, model processing and encoding
|
|
7982
|
+
remain with that engine. This factory supplies no speech engine or automatic
|
|
7983
|
+
browser/native provider selection.
|
|
7984
|
+
|
|
7985
|
+
### Members, results and events
|
|
7986
|
+
|
|
7987
|
+
The returned object has `name: 'speech'`, `current`, `subscribe`, `close`,
|
|
7988
|
+
`start`, `methods`, `drain` and `dispose`:
|
|
7989
|
+
|
|
7990
|
+
- `start(context)` subscribes and starts both configured engine loads
|
|
7991
|
+
independently, returning immediately. Core and status remain responsive
|
|
7992
|
+
during loading; one role's failure leaves the other usable.
|
|
7993
|
+
- `current()` and `methods['speech.status']()` return the same snapshot:
|
|
7994
|
+
`ready`, `transcriptionAvailable`, `synthesisAvailable`, `status`,
|
|
7995
|
+
`sttEngine`, `ttsEngine`, `roles.stt`, `roles.tts` and `closed`.
|
|
7996
|
+
`ready` requires both roles; each independent availability flag requires
|
|
7997
|
+
its model loaded in `ready` or `running` state while the service accepts work.
|
|
7998
|
+
`status` is `created`, `ok`, `closing` or `closed`; per-role state carries
|
|
7999
|
+
model loading, progress and complete errors. An omitted role is unavailable.
|
|
8000
|
+
- `subscribe(listener,{replay=true,signal}={})` replays current state by
|
|
8001
|
+
default and returns an unsubscribe function. Its signal owns only that
|
|
8002
|
+
subscription; a closed service can replay its final snapshot.
|
|
8003
|
+
- `methods['speech.transcribe'](request,context)` and
|
|
8004
|
+
`methods['speech.synthesize'](request,context)` are registered as the matching
|
|
8005
|
+
Core RPC methods. The context supplies `signal`, `requestId` and `emit`.
|
|
8006
|
+
The service publishes synchronous accepted `Thinking` before waiting for
|
|
8007
|
+
its role's load, then forwards the engine's complete progress and result.
|
|
8008
|
+
- `close()` and its `drain()` alias stop acceptance, abort the service lifetime,
|
|
8009
|
+
close both engines concurrently and await startup and request work. Repeated
|
|
8010
|
+
calls share one promise. `dispose()` also releases event subscriptions.
|
|
8011
|
+
|
|
8012
|
+
`speech.state` carries the complete snapshot. `speech.progress` carries
|
|
8013
|
+
`{requestId,role,status:'Thinking',progress}` with initial
|
|
8014
|
+
`progress:{phase:'accepted'}`. The service's subscription replays state; Core's
|
|
8015
|
+
generic runtime replay does not replay this custom event. Browser consumers
|
|
8016
|
+
subscribe before requesting `Arcane.speech.status()` and preserve any newer
|
|
8017
|
+
state event received while that request is pending.
|
|
8018
|
+
|
|
8019
|
+
### Cancellation, errors and availability
|
|
8020
|
+
|
|
8021
|
+
The optional factory signal owns the service lifetime. A request signal is
|
|
8022
|
+
combined with that lifetime and reaches its selected engine. Cancelling one
|
|
8023
|
+
request waiting for a shared load settles that request without cancelling
|
|
8024
|
+
the other requests or role. No later cancelled progress or result is delivered.
|
|
8025
|
+
Actual queued/running native interruption belongs to the engine; it must settle
|
|
8026
|
+
before Core reaches service shutdown, because Core first cancels and awaits
|
|
8027
|
+
active requests.
|
|
8028
|
+
|
|
8029
|
+
Invalid engine interfaces or listeners throw `TypeError`. Missing roles reject
|
|
8030
|
+
their operation with `SPEECH_ENGINE_UNAVAILABLE`; work after shutdown begins
|
|
8031
|
+
rejects with `CORE_CLOSING`. Engine errors remain observable, and engine cleanup
|
|
8032
|
+
failures reject shutdown with `AggregateError`. Asynchronous listener failures
|
|
8033
|
+
reach developer diagnostics. Engine platform support remains its own contract;
|
|
8034
|
+
this Node composition layer adds no engine dependency. Existing AI readiness
|
|
8035
|
+
consumers recognize `whisper.cpp` and `kokoro-onnx` IDs independently of the
|
|
8036
|
+
service's engine-neutral interface. See the [complete engine and lifetime
|
|
8037
|
+
contract](native-speech.md).
|
|
8038
|
+
|
|
8039
|
+
## createSpeechService default export
|
|
8040
|
+
|
|
8041
|
+
The default export from `arcane-os/core/speech` is the same
|
|
8042
|
+
`createSpeechService` factory, with identical inputs, results and lifecycle.
|
|
8043
|
+
|
|
8044
|
+
## prepareCoreModelAssets()
|
|
8045
|
+
|
|
8046
|
+
`prepareCoreModelAssets({client=getInstalledCoreClient(),workingDirectory,members,signal?,onProgress?})`
|
|
8047
|
+
from `arcane-os/ai/core-model-assets` projects ordered complete
|
|
8048
|
+
`members: [{path,file}]` through an available Core connection. Each `file` is a
|
|
8049
|
+
Blob or File. It returns `{id,directory,members:[{path,nativePath}],release}`
|
|
8050
|
+
after all members finish writing and close. Independent members transfer
|
|
8051
|
+
concurrently; each member's writes remain ordered.
|
|
8052
|
+
|
|
8053
|
+
The caller releases preparation ownership with asynchronous idempotent
|
|
8054
|
+
`release()`. Native engines acquire their own retain handle before loading,
|
|
8055
|
+
and files remain until their actual native use ends. Cancellation and failure
|
|
8056
|
+
join transfers and uncancelled cleanup, preserving complete original errors.
|
|
8057
|
+
The helper downloads no model, changes no DBOPFS original and selects no
|
|
8058
|
+
engine. See [complete preparation and cleanup usage](model-assets.md).
|
|
8059
|
+
|
|
8060
|
+
## createModelAssetService()
|
|
8061
|
+
|
|
8062
|
+
`createModelAssetService({appRoot=process.cwd()}={})` from
|
|
8063
|
+
`arcane-os/core/model-assets` returns the Core service for
|
|
8064
|
+
`modelAssets.open/write/complete/release/status` and `modelAssets.state`.
|
|
8065
|
+
Relative working directories resolve from `appRoot`; explicit absolute
|
|
8066
|
+
directories remain caller-selected. Each projection has its own child
|
|
8067
|
+
directory and complete member files.
|
|
8068
|
+
|
|
8069
|
+
`current()` returns `{closing,projections}`. `retain(id)` accepts a completed
|
|
8070
|
+
projection and returns `{id,directory,members,release}` for a native owner.
|
|
8071
|
+
`dispose()` releases preparation ownership and joins file writes, closes and
|
|
8072
|
+
all native retain lifetimes before cleanup. The native owner releases its
|
|
8073
|
+
handle only after its actual context/worker use ends. Original stored model
|
|
8074
|
+
files remain with their application owner. See
|
|
8075
|
+
[working-file service and wire operations](model-assets.md#native-ownership).
|
|
8076
|
+
|
|
8077
|
+
## createModelAssetService default export
|
|
8078
|
+
|
|
8079
|
+
The default export from `arcane-os/core/model-assets` is the same
|
|
8080
|
+
`createModelAssetService` factory and lifecycle described above.
|
|
8081
|
+
|
|
7764
8082
|
## createLocalAIService default export
|
|
7765
8083
|
|
|
7766
8084
|
The default binding from `arcane-os/core/local-ai` is exactly the named
|
|
@@ -7776,7 +8094,7 @@ import createLocalAIService from 'arcane-os/core/local-ai';
|
|
|
7776
8094
|
### Overview
|
|
7777
8095
|
|
|
7778
8096
|
Reuses matching managed runtimes or installs complete selected official
|
|
7779
|
-
llama.cpp/Ollama/ONNX distributions or NeMo libraries in an explicitly supplied directory.
|
|
8097
|
+
llama.cpp/Ollama/ONNX/image distributions or NeMo libraries in an explicitly supplied directory.
|
|
7780
8098
|
|
|
7781
8099
|
### Signature and result
|
|
7782
8100
|
|
|
@@ -7787,7 +8105,11 @@ async ensureLocalAIRuntimes({runtimes=[],directory,platform=process.platform,arc
|
|
|
7787
8105
|
Import it from `arcane-os/local-ai`. Runtime requirements accept IDs or
|
|
7788
8106
|
`{id,version?,url?}` records. The result is an array of absolute
|
|
7789
8107
|
`{id,version,platform,architecture,root}` records, with `executable` for servers,
|
|
7790
|
-
`modulePath` for ONNX,
|
|
8108
|
+
`modulePath` for ONNX, image `libraryPath`/`bindingModulePath`/`variants`/`models`,
|
|
8109
|
+
or NeMo library directories. Image requirements also accept `backend` and
|
|
8110
|
+
`models`; their pinned default runtime, CPU/Metal selection and separate model
|
|
8111
|
+
preparation are described in [local image generation](local-image-generation.md).
|
|
8112
|
+
Matching concurrent
|
|
7791
8113
|
installs share their work. Downloads retain runtime libraries and surface
|
|
7792
8114
|
network/archive failures; cancellation and operation events remain observable.
|
|
7793
8115
|
Installation changes no global PATH or system service and loads no model.
|
|
@@ -7825,6 +8147,13 @@ contains the complete emitted inventory. Existing runtime destinations are
|
|
|
7825
8147
|
preserved and reported as a conflict. Copying settles all started work and
|
|
7826
8148
|
reports failures/cancellation without executing app services or models.
|
|
7827
8149
|
|
|
8150
|
+
Image records relocate the complete library, binding and variant paths. Model
|
|
8151
|
+
URL descriptors retain their original acquisition metadata for preparation
|
|
8152
|
+
after launch. Runtime-contained native model paths become artifact-relative;
|
|
8153
|
+
external working paths report their portability incompatibility rather than
|
|
8154
|
+
embedding this machine's path. Use the application-owned native-resource or
|
|
8155
|
+
post-launch model-assets workflow for those files.
|
|
8156
|
+
|
|
7828
8157
|
```javascript
|
|
7829
8158
|
import {bundleLocalAIRuntimes} from 'arcane-os/local-ai';
|
|
7830
8159
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.64.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",
|
|
@@ -61,17 +61,21 @@
|
|
|
61
61
|
"./core/runtime": "./src/core/runtime.mjs",
|
|
62
62
|
"./core/stdio": "./src/core/stdio.mjs",
|
|
63
63
|
"./core/host": "./src/core/host.mjs",
|
|
64
|
+
"./core/repositories": "./src/core/repositories.mjs",
|
|
64
65
|
"./core/packaged-web": "./src/core/services/packaged-web.mjs",
|
|
65
66
|
"./core/preferences": "./src/core/services/preferences.mjs",
|
|
66
67
|
"./core/diarization": "./src/diarization/service.mjs",
|
|
67
68
|
"./core/local-ai": "./src/core/services/local-ai.mjs",
|
|
68
69
|
"./core/image": "./src/core/services/image.mjs",
|
|
70
|
+
"./core/speech": "./src/core/services/speech.mjs",
|
|
69
71
|
"./core/model-assets": "./src/core/services/model-assets.mjs",
|
|
70
72
|
"./diarization": "./src/diarization/index.mjs",
|
|
71
73
|
"./diarization/build": "./src/diarization/build.mjs",
|
|
72
74
|
"./local-ai": "./src/local-ai/install.mjs",
|
|
73
75
|
"./local-ai/onnx": "./src/local-ai/onnx.mjs",
|
|
74
76
|
"./local-ai/image": "./src/local-ai/image-runtime.mjs",
|
|
77
|
+
"./local-ai/whisper": "./src/local-ai/whisper/index.mjs",
|
|
78
|
+
"./local-ai/whisper/build": "./src/local-ai/whisper/build.mjs",
|
|
75
79
|
"./integrated-provider": "./src/integrated-provider-loader.mjs",
|
|
76
80
|
"./packager": "./src/packager/core.mjs",
|
|
77
81
|
"./release-bundle": "./src/release-bundle.mjs",
|
|
@@ -295,6 +295,7 @@
|
|
|
295
295
|
const aiModuleImport = import('../modules/AI.js');
|
|
296
296
|
const providerRuntimeImport = import('../modules/AIProviderRuntime.js');
|
|
297
297
|
const {
|
|
298
|
+
continuesAIRuntimeOperation,
|
|
298
299
|
requestAIRuntimeIntent,
|
|
299
300
|
subscribeAIRuntimeState
|
|
300
301
|
} = await import('../modules/AIRuntimeState.js');
|
|
@@ -366,6 +367,7 @@
|
|
|
366
367
|
let ttsIntentGeneration = 0;
|
|
367
368
|
let eventOperationSequence = 0;
|
|
368
369
|
let transcriptionOperationId = null;
|
|
370
|
+
let transcriptionRuntimeOperationId = null;
|
|
369
371
|
let ttsOperationId = null;
|
|
370
372
|
let destroyed = false;
|
|
371
373
|
let recognitionLanguage = is.string(host.recognitionLanguage)
|
|
@@ -826,8 +828,10 @@
|
|
|
826
828
|
|
|
827
829
|
function applyRoleTransitions(previousSTTRole, previousTTSRole) {
|
|
828
830
|
sttActivationController?.synchronize(sttRole);
|
|
829
|
-
const
|
|
830
|
-
&& sttRole
|
|
831
|
+
const continuingTranscription = transcriptionActive && !nativeCaptureSession
|
|
832
|
+
&& continuesAIRuntimeOperation(previousSTTRole, sttRole, transcriptionRuntimeOperationId);
|
|
833
|
+
const sttBecameUnready = ['ready', 'recovering'].includes(previousSTTRole.state)
|
|
834
|
+
&& sttRole.state !== 'ready' && !continuingTranscription;
|
|
831
835
|
const ttsBecameUnready = previousTTSRole.state === 'ready'
|
|
832
836
|
&& ttsRole.state !== 'ready';
|
|
833
837
|
|
|
@@ -2011,10 +2015,16 @@
|
|
|
2011
2015
|
throw error;
|
|
2012
2016
|
}
|
|
2013
2017
|
|
|
2014
|
-
const
|
|
2018
|
+
const previousRuntimeOperationId = providerRuntime.status('stt').operationId;
|
|
2019
|
+
const pendingTranscription = aiRuntime.fetchSTT(
|
|
2015
2020
|
audioFile,
|
|
2016
2021
|
controller.signal
|
|
2017
2022
|
);
|
|
2023
|
+
const activeRole = providerRuntime.status('stt');
|
|
2024
|
+
transcriptionRuntimeOperationId = activeRole.busy
|
|
2025
|
+
&& activeRole.operationId !== previousRuntimeOperationId
|
|
2026
|
+
? activeRole.operationId : null;
|
|
2027
|
+
const transcription = await pendingTranscription;
|
|
2018
2028
|
if (
|
|
2019
2029
|
generation !== transcriptionGeneration
|
|
2020
2030
|
|| sttRole.state !== 'ready'
|
|
@@ -2044,6 +2054,7 @@
|
|
|
2044
2054
|
} finally {
|
|
2045
2055
|
if (transcriptionAbortController === controller) {
|
|
2046
2056
|
transcriptionAbortController = null;
|
|
2057
|
+
transcriptionRuntimeOperationId = null;
|
|
2047
2058
|
}
|
|
2048
2059
|
if (generation === transcriptionGeneration) {
|
|
2049
2060
|
transcriptionActive = false;
|
|
@@ -2144,6 +2155,7 @@
|
|
|
2144
2155
|
transcriptionGeneration += 1;
|
|
2145
2156
|
transcriptionAbortController?.abort();
|
|
2146
2157
|
transcriptionAbortController = null;
|
|
2158
|
+
transcriptionRuntimeOperationId = null;
|
|
2147
2159
|
recordingRequested = false;
|
|
2148
2160
|
transcriptionActive = false;
|
|
2149
2161
|
clearSilenceTimer();
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
const [
|
|
136
136
|
{default:MD},
|
|
137
137
|
{appendTranscription,createSTTActivationController,normalizeVoiceOptions},
|
|
138
|
-
{requestAIRuntimeIntent,subscribeAIRuntimeState},
|
|
138
|
+
{continuesAIRuntimeOperation,requestAIRuntimeIntent,subscribeAIRuntimeState},
|
|
139
139
|
{default:ContinuousVoiceCapture},
|
|
140
140
|
{getAIProviderRuntime}
|
|
141
141
|
]=await Promise.all([
|
|
@@ -165,6 +165,7 @@
|
|
|
165
165
|
let recorder=null;
|
|
166
166
|
let state='idle';
|
|
167
167
|
let stateMessage='';
|
|
168
|
+
let transcriptionRuntimeOperationId=null;
|
|
168
169
|
let sttRole=unavailableRole('stt');
|
|
169
170
|
let transcript='';
|
|
170
171
|
let sessionGeneration=0;
|
|
@@ -1121,7 +1122,17 @@
|
|
|
1121
1122
|
error.code='ARCANE_VOICE_TRANSCRIPTION_STT_RUNTIME_METHOD_UNAVAILABLE';
|
|
1122
1123
|
throw error;
|
|
1123
1124
|
}
|
|
1124
|
-
|
|
1125
|
+
const previousOperationId=providerRuntime.status('stt').operationId;
|
|
1126
|
+
const pending=globalThis.ai.fetchSTT(file,signal);
|
|
1127
|
+
const activeRole=providerRuntime.status('stt');
|
|
1128
|
+
const operationId=activeRole.busy&&activeRole.operationId!==previousOperationId
|
|
1129
|
+
?activeRole.operationId:null;
|
|
1130
|
+
transcriptionRuntimeOperationId=operationId;
|
|
1131
|
+
try{
|
|
1132
|
+
return await pending;
|
|
1133
|
+
}finally{
|
|
1134
|
+
if(transcriptionRuntimeOperationId===operationId)transcriptionRuntimeOperationId=null;
|
|
1135
|
+
}
|
|
1125
1136
|
}
|
|
1126
1137
|
|
|
1127
1138
|
function isTranscriptionCancellation(error,controller){
|
|
@@ -1417,6 +1428,9 @@
|
|
|
1417
1428
|
function synchronizeAIRuntimeState(snapshot){
|
|
1418
1429
|
const previousRole=sttRole;
|
|
1419
1430
|
sttRole=snapshot.roles.stt;
|
|
1431
|
+
const continuingTranscription=continuesAIRuntimeOperation(
|
|
1432
|
+
previousRole,sttRole,transcriptionRuntimeOperationId
|
|
1433
|
+
);
|
|
1420
1434
|
if(sttRole.state==='error'&&previousRole.state!=='error'){
|
|
1421
1435
|
arcaneLogging.error('Arcane transcription runtime failed.',sttRole.error);
|
|
1422
1436
|
}
|
|
@@ -1438,6 +1452,7 @@
|
|
|
1438
1452
|
return;
|
|
1439
1453
|
}
|
|
1440
1454
|
if(session.processing==='transcribing'
|
|
1455
|
+
&&!continuingTranscription
|
|
1441
1456
|
&&(sttRole.state!=='ready'
|
|
1442
1457
|
||previousRole.providerId!==sttRole.providerId
|
|
1443
1458
|
||previousRole.modelId!==sttRole.modelId)){
|
|
@@ -1447,7 +1462,8 @@
|
|
|
1447
1462
|
renderContinuousState(session);
|
|
1448
1463
|
return;
|
|
1449
1464
|
}
|
|
1450
|
-
if(
|
|
1465
|
+
if(['ready','recovering'].includes(previousRole.state)
|
|
1466
|
+
&&sttRole.state!=='ready'&&!continuingTranscription){
|
|
1451
1467
|
if(cancelSTTOperation('runtime-unready')){
|
|
1452
1468
|
return;
|
|
1453
1469
|
}
|