arcane-os 0.59.0 → 0.60.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 +32 -0
- package/README.md +1 -1
- package/browser-runtime/ai/core-model-assets.mjs +152 -0
- package/browser-runtime/core/client.mjs +9 -1
- package/browser-runtime/core/contracts.mjs +5 -0
- package/docs/reference/README.md +3 -0
- package/docs/reference/core/arcane-ai-contracts.md +31 -2
- package/docs/reference/core/arcane-api.md +13 -2
- package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +28 -16
- package/docs/reference/core/reference/arcane-api/namespaces.md +14 -0
- package/docs/reference/core-client.md +74 -0
- package/docs/reference/core-native-packaging.md +66 -2
- package/docs/reference/inventory/package-api.json +2 -2
- package/docs/reference/inventory/runtime-modules.json +2 -2
- package/docs/reference/local-image-editing.md +79 -0
- package/docs/reference/model-assets.md +144 -0
- package/docs/reference/runtime-modules.md +37 -5
- package/docs/reference/sdk-api.md +53 -8
- package/package.json +3 -3
- package/runtime/arcane/modules/AI.js +28 -12
- package/runtime/arcane/modules/ThemeBootstrap.js +217 -2
- package/src/core/hosts/windows/ArcaneHost.cs +211 -0
- package/src/core/hosts/windows/ArcaneLauncher.cs +5 -0
- package/src/core/services/model-assets.mjs +267 -0
- package/src/local-ai/image-editing.mjs +159 -0
- package/src/native/windows-icon.mjs +582 -0
- package/src/native/windows-provider.mjs +60 -2
|
@@ -3898,7 +3898,7 @@
|
|
|
3898
3898
|
"summary": "Projects a Core client into the established application-facing Arcane namespace.",
|
|
3899
3899
|
"availability": "Browser and native WebView JavaScript hosts with a Core client",
|
|
3900
3900
|
"protocol": "arcane/1 compatibility facade",
|
|
3901
|
-
"normalization": "Routes
|
|
3901
|
+
"normalization": "Routes namespace methods through client.invoke while retaining operation-specific parameters, correlation, streaming callbacks, timeouts and cancellation; window.setTheme(presentation,{signal}?) forwards the complete per-window backgroundColor/textColor record, with omitted fields unchanged and null reset, and returns the host's actual applied/unsupported result without changing system appearance"
|
|
3902
3902
|
},
|
|
3903
3903
|
{
|
|
3904
3904
|
"id": "core-client:installCoreClient",
|
|
@@ -4052,7 +4052,7 @@
|
|
|
4052
4052
|
"summary": "Assembles selected application services and browser content with the SDK-owned Windows x64 WebView2 and SEA host.",
|
|
4053
4053
|
"availability": "Node for assembly; Windows x64 with WebView2 Runtime for execution",
|
|
4054
4054
|
"protocol": "arcane-native-builder/1 windows-x64 provider",
|
|
4055
|
-
"normalization": "Uses a selected hostDirectory or the exact installed SDK version's numeric release asset; preserves complete payloads; run cancellation closes stdin and waits for host-owned graceful shutdown"
|
|
4055
|
+
"normalization": "Uses a selected hostDirectory or the exact installed SDK version's numeric release asset; preserves complete payloads; native.icon PNG/ICO derives the copied executable and host.icon without an app compiler, while other formats retain assembly with native.icon.unsupported and executableIcon:false; the matching host loads the selected window/taskbar icon and handles window.setTheme with per-field applied/unsupported results; run cancellation closes stdin and waits for host-owned graceful shutdown"
|
|
4056
4056
|
},
|
|
4057
4057
|
{
|
|
4058
4058
|
"id": "native-windows-provider:arcaneNativeBuilderProvider",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"availability": "Browser + native bridge + TWiN Cloud",
|
|
31
31
|
"protocol": "arcane-ai-browser-speech-configuration/1, AIProviderRuntime arcane-ai-provider/2 routes, globalThis.arcaneEvents, TWiN Cloud HTTPS, Arcane.ollama, Arcane.speech, Android WebView bridge",
|
|
32
32
|
"normalization": "Complete mutable caller-owned browser speech authority, SDK-owned provider registration/replacement/disposal, explicit STT/TTS activation, normalized Whisper STT and Kokoro TTS execution with default capacities 1 and 4 respectively, explicit provider-neutral execution snapshots through status(role,{execution:true}), sticky readiness, canonical window.user readiness without compatibility-event object-identity admission or polling, exact ordered structural calls with required arguments.message, atomic nonblank all-ID tool-result sequencing, complete all-choice streaming/data validation, native Ollama structural adaptation, complete-response then all validated tool callbacks then completion ordering, observed async callbacks, Blob/File transcription, automatic repeated-formatting-mark removal from cloned outbound TTS input while caller and visible content stays exact, immediate exact-segment synthesis, per-call voice/speed capture, optional final-segment pause on the existing audio clock, optional per-call terminal playback completion, detached preparation with complete semantic DBOPFS audio reuse and same-owner pending request sharing, independent prepared playback without a model load for cached audio, ordered audio-clock scheduling, playable audio, active-generation TTS operation-failure routing, mute, and cancellation are normalized; provider/model/runtime/voice policy remains caller-owned. Both speech roles default execution.device to auto: webnn-npu when navigator.ml.createContext is exposed, then webgpu when navigator.gpu is exposed, then wasm for CPU execution. Failed backend loads clean up the pool before trying fresh Workers with the same prepared model and dtype; explicit devices never fall back. STT capacity only accepts 1; TTS accepts 1 through 4. Execution snapshots expose requestedDevice, selectedDevice, maxConcurrentRequests, and activeRequestCount for both roles; selectedDevice is null while unloaded and names the successful upstream session backend request when loaded. It does not prove every operation used the physical NPU: WebNN unsupported operations may use WASM, and compatibility depends on the browser, driver, hardware, and graph.",
|
|
33
|
-
"surface": "prepareTTSPlayback(payload,signal) silently returns a real Blob or native-speech descriptor; native controls expose finished/released/state/error/pause/resume/stop, and actual release owns the playback lane. fetchTTS and durable prepareTTS report ARCANE_AI_TTS_AUDIO_EXPORT_UNAVAILABLE for native voices. Request-local model overrides remain exact and never mutate the configured model. Browser-speech protocol/event/error/reason constants; default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and `browserSpeechDescriptor`; explicit `providerRuntime.status(role,{execution:true})` snapshots; `streamTTS(text,end,options={})` with optional voice, speed, pauseAfterMs, and waitForPlayback; automatic speech-input cleanup with SDK-internal preparation metadata; `prepareTTS({parts,storage,identity,signal,onState})` returning ordered segments, state, ready, getAudio(index), and cancel(); `playPreparedTTS(prepared,{signal,onState})` returning state, error, finished, pause(), resume(), and stop() with one playback lane per AI and observational state/error callbacks; configure/dispose speech, route lifecycle, declaration-validated chat/stream requests with exact ordered calls; optional streamRequest toolText:{name,field} and onToolText(text,call,displayId) for decoded selected argument text with actual call identity, distinct from ordinary prose and terminal tool execution; synthesis/transcription and playback controls; initializes from current canonical user readiness, installs `window.ai`, and projects `ai-ready` plus active-generation `ai-tts-failure`."
|
|
33
|
+
"surface": "Native fetchTTS(payload,signal) and fetchSTT(audio,signal) forward caller cancellation separately from their complete Core speech payloads, normalize aborts to AbortError and suppress late results; actual engine interruption remains service-owned. prepareTTSPlayback(payload,signal) silently returns a real Blob or native-speech descriptor; native controls expose finished/released/state/error/pause/resume/stop, and actual release owns the playback lane. fetchTTS and durable prepareTTS report ARCANE_AI_TTS_AUDIO_EXPORT_UNAVAILABLE for native voices. Request-local model overrides remain exact and never mutate the configured model. Browser-speech protocol/event/error/reason constants; default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and `browserSpeechDescriptor`; explicit `providerRuntime.status(role,{execution:true})` snapshots; `streamTTS(text,end,options={})` with optional voice, speed, pauseAfterMs, and waitForPlayback; automatic speech-input cleanup with SDK-internal preparation metadata; `prepareTTS({parts,storage,identity,signal,onState})` returning ordered segments, state, ready, getAudio(index), and cancel(); `playPreparedTTS(prepared,{signal,onState})` returning state, error, finished, pause(), resume(), and stop() with one playback lane per AI and observational state/error callbacks; configure/dispose speech, route lifecycle, declaration-validated chat/stream requests with exact ordered calls; optional streamRequest toolText:{name,field} and onToolText(text,call,displayId) for decoded selected argument text with actual call identity, distinct from ordinary prose and terminal tool execution; synthesis/transcription and playback controls; initializes from current canonical user readiness, installs `window.ai`, and projects `ai-ready` plus active-generation `ai-tts-failure`."
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
"file": "runtime/arcane/modules/AIModelSelectionController.js",
|
|
@@ -1364,7 +1364,7 @@
|
|
|
1364
1364
|
"availability": "Browser/native hybrid",
|
|
1365
1365
|
"protocol": "ThemeManager + host Arcane.events projected once through the per-realm globalThis.arcaneEvents authority",
|
|
1366
1366
|
"normalization": "Theme state normalized; storage/native errors mixed.",
|
|
1367
|
-
"surface": "`bootstrapArcaneTheme()`, `disposeArcaneThemeBootstrap()`, `arcaneThemeReady`, and default ready promise. Shared bootstrap replays an already-ready User and
|
|
1367
|
+
"surface": "`bootstrapArcaneTheme()`, `disposeArcaneThemeBootstrap()`, `arcaneThemeReady`, and default ready promise. Shared bootstrap replays an already-ready User. In native hosts it independently forwards computed --background/--text-color through Arcane.window.setTheme, observing shared theme events, root/body presentation attributes, stylesheets, device scheme and page restoration; browser CSS resolution retains alpha and converts modern colors to sRGB. Disposal releases appearance/user/theme subscriptions, native sampling observers and listeners, and pending window requests. Ordinary browsers remain silent. Presentation cache is nonauthoritative; use classic ThemePresentation after app-id and before CSS for early restoration."
|
|
1368
1368
|
},
|
|
1369
1369
|
{
|
|
1370
1370
|
"file": "runtime/arcane/modules/ThemeManager.js",
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Local image edit inputs
|
|
2
|
+
|
|
3
|
+
The SDK input decoder prepares a PNG raster for the shared native image
|
|
4
|
+
runtime. Decoding does not load a model or perform inference. The runtime owns
|
|
5
|
+
model selection, supported editing operations, native calls and their complete
|
|
6
|
+
results. Applications retain the original image and decide whether to save a
|
|
7
|
+
newly generated result.
|
|
8
|
+
|
|
9
|
+
## Decoder contract
|
|
10
|
+
|
|
11
|
+
`src/local-ai/image-editing.mjs` exports the internal worker function
|
|
12
|
+
`decodeImage({data, mediaType, signal})`.
|
|
13
|
+
|
|
14
|
+
| Field | Contract |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| `data` | Complete encoded PNG in a `Uint8Array`; a Node `Buffer` is also accepted. Only the supplied view is read. |
|
|
17
|
+
| `mediaType` | `image/png`, an empty string, or omitted. The PNG signature is read from the actual input. Other declared formats report unsupported input. |
|
|
18
|
+
| `signal` | Optional `AbortSignal` belonging to the image request. |
|
|
19
|
+
|
|
20
|
+
The promise returns `{width, height, channel, data}`. Dimensions come from the
|
|
21
|
+
source raster; `channel` is `3` for RGB or `4` for RGBA. Returned `data` is a
|
|
22
|
+
separate contiguous `Uint8Array` containing interleaved samples, with pixels
|
|
23
|
+
ordered left to right and rows ordered top to bottom. The native request owner
|
|
24
|
+
retains this allocation until the native operation actually completes,
|
|
25
|
+
including after a cancellation request.
|
|
26
|
+
|
|
27
|
+
Input decoding accepts static, non-interlaced, 8-bit RGB and RGBA PNGs, all
|
|
28
|
+
five PNG row filters, and image data spread across multiple `IDAT` chunks.
|
|
29
|
+
RGB transparent-color information is represented as RGBA. An optional suggested
|
|
30
|
+
palette on an RGB or RGBA image does not change its color type.
|
|
31
|
+
|
|
32
|
+
Indexed-color, grayscale, 16-bit, interlaced and animated PNGs currently report
|
|
33
|
+
unsupported input. JPEG and WebP are also unsupported by this decoder. The
|
|
34
|
+
decoder does not silently convert those formats or select one animation frame.
|
|
35
|
+
|
|
36
|
+
The original encoded image is copied for the operation and never modified or
|
|
37
|
+
detached. Decoding preserves stored color samples and straight alpha, including
|
|
38
|
+
RGB values underneath transparent pixels. It does not composite onto a chosen
|
|
39
|
+
background, rotate pixels from metadata, apply a color-profile conversion,
|
|
40
|
+
resize, crop or create a file. Metadata remains in the original image; the
|
|
41
|
+
native raster record contains pixels and dimensions only.
|
|
42
|
+
|
|
43
|
+
## Execution and cancellation
|
|
44
|
+
|
|
45
|
+
Invoke the decoder inside the shared image runtime's existing worker.
|
|
46
|
+
Inflation uses asynchronous Node zlib. Row reconstruction yields between
|
|
47
|
+
scanlines so the worker can receive cancellation. An abort during inflation is
|
|
48
|
+
observed after that native operation settles; it does not claim instant
|
|
49
|
+
interruption. A cancelled decode returns no raster for inference.
|
|
50
|
+
|
|
51
|
+
`ARCANE_IMAGE_INPUT_UNSUPPORTED` describes an unavailable input format or
|
|
52
|
+
encoding. `ARCANE_IMAGE_DECODE_FAILED` describes unreadable PNG structure or
|
|
53
|
+
scanlines. Node zlib failures retain their complete original errors, and
|
|
54
|
+
cancellation retains the owning signal's reason or Node `AbortError`. A decode
|
|
55
|
+
failure never returns partial imagery or substitutes a different image.
|
|
56
|
+
|
|
57
|
+
## Editing semantics at the native owner
|
|
58
|
+
|
|
59
|
+
Whole-image img2img uses an initial image, prompt and strength. Masked editing
|
|
60
|
+
adds a separate mask; instruction/reference editing uses a model that supports
|
|
61
|
+
reference conditioning. These are distinct operations and must be advertised
|
|
62
|
+
only when the selected model and native path implement them. Ordinary img2img
|
|
63
|
+
does not require LoRA training. The candidate engine documents this directly
|
|
64
|
+
with its base SD1.4 model in the
|
|
65
|
+
[tagged img2img example](https://github.com/leejet/stable-diffusion.cpp/blob/master-929-3f8527a/docs/sd.md#img2img-example).
|
|
66
|
+
|
|
67
|
+
Source dimensions are decoder output, not an implicit request to change the
|
|
68
|
+
generation dimensions. The model owner documents its actual canvas adaptation
|
|
69
|
+
and reports actual output dimensions. In the candidate engine, temporary
|
|
70
|
+
initial images use model preprocessing while caller images remain unchanged;
|
|
71
|
+
even `mode=none` does not suppress all later model adaptation. See the
|
|
72
|
+
[native preprocessing contract](https://github.com/leejet/stable-diffusion.cpp/blob/master-929-3f8527a/docs/image_preprocessing.md).
|
|
73
|
+
|
|
74
|
+
An RGB-only model such as the selected SD1.4 candidate consumes the stored RGB
|
|
75
|
+
and does not preserve alpha. The SDK must not silently choose a compositing
|
|
76
|
+
background or claim that passing RGBA preserves its displayed appearance.
|
|
77
|
+
Strength zero is also not an exact-copy operation: native img2img still uses
|
|
78
|
+
the model's encode, sampling and decode path. These model behaviors are
|
|
79
|
+
separate from the decoder preserving the original input.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Native working files from stored model assets
|
|
2
|
+
|
|
3
|
+
The selected `0.60.0` package contains the model-assets helpers as internal
|
|
4
|
+
preparation. The public imports and Core registration shown below belong to
|
|
5
|
+
the pending local-image integration and are unavailable through `0.60.0`.
|
|
6
|
+
These examples document that integration's intended public contract.
|
|
7
|
+
|
|
8
|
+
`prepareCoreModelAssets()` streams complete browser `File` or `Blob` members
|
|
9
|
+
through the existing Core connection into native working files. DBOPFS keeps
|
|
10
|
+
the authoritative originals. The helper performs no model download and changes
|
|
11
|
+
neither stored content nor the model format.
|
|
12
|
+
|
|
13
|
+
Use complete members returned by `createDbopfsModelStore().ensure()` or files
|
|
14
|
+
read from the application's existing DBOPFS owner. The browser model store
|
|
15
|
+
already assembles persisted Range parts into one logical Blob per upstream
|
|
16
|
+
member. Preserve that member order and the original relative filenames,
|
|
17
|
+
including companion files required by a model.
|
|
18
|
+
|
|
19
|
+
## Browser preparation
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
import {prepareCoreModelAssets} from 'arcane-os/ai/core-model-assets';
|
|
23
|
+
import {createCoreImageRuntime} from 'arcane-os/ai/core-image';
|
|
24
|
+
|
|
25
|
+
const stored = await modelStore.ensure(selectedSource, {signal});
|
|
26
|
+
const projection = await prepareCoreModelAssets({
|
|
27
|
+
client,
|
|
28
|
+
workingDirectory: selectedWorkingDirectory,
|
|
29
|
+
members: [{path: 'sd-v1-4.ckpt', file: stored.files[0]}],
|
|
30
|
+
signal,
|
|
31
|
+
onProgress: renderPreparationProgress
|
|
32
|
+
});
|
|
33
|
+
const image = createCoreImageRuntime({client});
|
|
34
|
+
try {
|
|
35
|
+
await image.load({
|
|
36
|
+
model: 'sd14',
|
|
37
|
+
assetProjectionId: projection.id,
|
|
38
|
+
resourcePaths: {model: 'sd-v1-4.ckpt'},
|
|
39
|
+
signal
|
|
40
|
+
});
|
|
41
|
+
} finally {
|
|
42
|
+
// Native loading takes its own retain handle before using these files.
|
|
43
|
+
await projection.release();
|
|
44
|
+
}
|
|
45
|
+
const result = await image.generate({
|
|
46
|
+
model: 'sd14',
|
|
47
|
+
prompt: 'A dignified raccoon who has been put in charge of the moon.',
|
|
48
|
+
signal
|
|
49
|
+
});
|
|
50
|
+
// Display or save the complete returned image through the application owner.
|
|
51
|
+
await image.unload();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This example assumes that the application selected the `sd14` model and its
|
|
55
|
+
complete checkpoint source. Model choice, download approval, prompts, output
|
|
56
|
+
storage and the selected working directory remain application-owned.
|
|
57
|
+
|
|
58
|
+
`prepareCoreModelAssets({client,workingDirectory,members,signal,onProgress})`
|
|
59
|
+
requires an available Core connection exposing the model-assets service.
|
|
60
|
+
`client` defaults to the installed Core client. Every member is
|
|
61
|
+
`{path,file}`, where `path` is its relative filename or companion-file path and
|
|
62
|
+
`file` is the complete stored Blob or File. Relative working-directory paths
|
|
63
|
+
resolve from the native service's `appRoot`; an application may explicitly
|
|
64
|
+
select an absolute working directory.
|
|
65
|
+
|
|
66
|
+
The result contains `id`, `directory`, ordered
|
|
67
|
+
`members: [{path,nativePath}]`, and an idempotent asynchronous `release()`.
|
|
68
|
+
The operation creates a unique child directory under the selected working
|
|
69
|
+
directory. Member paths identify files inside that child directory. Original
|
|
70
|
+
DBOPFS files remain untouched.
|
|
71
|
+
|
|
72
|
+
Each incoming Blob stream chunk is encoded only for the existing JSON Core
|
|
73
|
+
transport. The helper waits for the corresponding native write before reading
|
|
74
|
+
the next chunk of that member. Independent members transfer concurrently;
|
|
75
|
+
the complete member set is returned only after every write and file close
|
|
76
|
+
finishes. There is no complete-model transport buffer or application content
|
|
77
|
+
limit. Progress reports actual preparation phases and member paths.
|
|
78
|
+
|
|
79
|
+
Cancellation stops active readers and requests. Failure joins the participating
|
|
80
|
+
transfers and requests native cleanup; that cleanup joins actual file writes
|
|
81
|
+
before removing the projection. Cleanup uses its own uncancelled operation so
|
|
82
|
+
an already-aborted preparation signal cannot skip it. Original failures and
|
|
83
|
+
cleanup failures remain observable.
|
|
84
|
+
|
|
85
|
+
## Native ownership
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
import {createModelAssetService} from 'arcane-os/core/model-assets';
|
|
89
|
+
|
|
90
|
+
const modelAssets = createModelAssetService({appRoot});
|
|
91
|
+
// Register this same service with Core and pass it to the native engine owner.
|
|
92
|
+
const use = modelAssets.retain(projectionId);
|
|
93
|
+
try {
|
|
94
|
+
// Load and use the complete files from use.members.
|
|
95
|
+
await ownNativeModelLifetime(use.members);
|
|
96
|
+
} finally {
|
|
97
|
+
// ownNativeModelLifetime must join actual model release before returning.
|
|
98
|
+
await use.release();
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`createModelAssetService({appRoot})` returns a Core service with `current()`,
|
|
103
|
+
`retain(id)` and `dispose()`. `retain()` accepts only a completed projection
|
|
104
|
+
and returns `{id,directory,members,release}`. A native engine takes this handle
|
|
105
|
+
before loading and releases it after actual unload, failed-load cleanup or
|
|
106
|
+
worker exit. A rejected inference/load promise alone does not establish native
|
|
107
|
+
release. Multiple contexts can retain one prepared set, and repeated inference
|
|
108
|
+
on a retained context reuses its files.
|
|
109
|
+
|
|
110
|
+
The browser's `projection.release()` relinquishes preparation ownership. It
|
|
111
|
+
does not delete files retained by a native engine. Deletion follows the final
|
|
112
|
+
native release and removes only that operation's working directory. Core closes
|
|
113
|
+
independent services concurrently, so the model-assets service waits for all
|
|
114
|
+
native retain handles during disposal instead of assuming service order.
|
|
115
|
+
Owners must release their handles after joining their actual engine lifetime.
|
|
116
|
+
|
|
117
|
+
Closing a browser accessor does not by itself establish native unload.
|
|
118
|
+
Explicitly release unused prepared projections. Core disposal also releases
|
|
119
|
+
preparation ownership and cleans up after retained engine uses end.
|
|
120
|
+
|
|
121
|
+
`current()` returns `{closing,projections}`. Each projection reports its `id`,
|
|
122
|
+
`directory`, `state`, ordered `members`, `preparationOwned`, number of native
|
|
123
|
+
`uses`, and `error`. Core emits `modelAssets.state` for lifecycle changes.
|
|
124
|
+
|
|
125
|
+
## Core transport operations
|
|
126
|
+
|
|
127
|
+
| Method | Parameters | Result |
|
|
128
|
+
| --- | --- | --- |
|
|
129
|
+
| `modelAssets.open` | `{id,workingDirectory,members:[{path}]}` | Preparing projection and native member paths |
|
|
130
|
+
| `modelAssets.write` | `{id,memberIndex,contentBase64}` | `{id,memberIndex,written:true}` after the native write |
|
|
131
|
+
| `modelAssets.complete` | `{id}` | Ready projection after all files close |
|
|
132
|
+
| `modelAssets.release` | `{id}` | Released preparation ownership; native uses may retain the files |
|
|
133
|
+
| `modelAssets.status` | `{}` | Current projection lifecycle records |
|
|
134
|
+
|
|
135
|
+
The browser helper owns this transport sequence. Correlation IDs identify
|
|
136
|
+
operations; they are unrelated to content identity. Original model files remain
|
|
137
|
+
separate and complete. A retry creates a new working projection from the stored
|
|
138
|
+
assets; it does not redownload them or replace the authoritative DBOPFS record.
|
|
139
|
+
|
|
140
|
+
The implementation uses browser streams, the existing portable Core JSON
|
|
141
|
+
transport and Node filesystem operations. Native paths and cleanup follow the
|
|
142
|
+
host's Windows, Linux or macOS filesystem behavior. Android requires its host's
|
|
143
|
+
Core/filesystem adaptation. These are source-level platform contracts, not a
|
|
144
|
+
claim of execution on every target.
|
|
@@ -387,8 +387,12 @@ existing `audioFormat` when the catalog does not declare response formats. When
|
|
|
387
387
|
the selected model declares `speech.responseFormats`, that setting is used only when supported; if
|
|
388
388
|
the setting is the instance's `opus` default and the model rejects it, the catalog's
|
|
389
389
|
`speech.defaultResponseFormat` is used, while any other unsupported setting is
|
|
390
|
-
rejected. It propagates the caller-owned signal and returns a playable `Blob
|
|
391
|
-
|
|
390
|
+
rejected. It propagates the caller-owned signal and returns a playable `Blob`.
|
|
391
|
+
The native `LOCAL_SPEACH` route forwards that signal separately from its
|
|
392
|
+
synthesis payload to `Arcane.speech.synthesize(request, {signal})`; Core aborts
|
|
393
|
+
are normalized to `AbortError` with `ARCANE_AI_REQUEST_ABORTED`. Actual engine
|
|
394
|
+
interruption belongs to the registered service. It does not independently
|
|
395
|
+
choose a provider, cloud fallback, model, runtime, or
|
|
392
396
|
voice policy for the application. Every call removes repeated same formatting
|
|
393
397
|
marks from a cloned outbound input before delegation; the caller's payload stays
|
|
394
398
|
unchanged. The third `preparation` argument is reserved for SDK-internal
|
|
@@ -529,8 +533,11 @@ operation boundary, generation, and stable reason. Muting, explicit
|
|
|
529
533
|
cancellation, permission waiting, and superseded generations do not emit a
|
|
530
534
|
failure. The operation event does not rewrite provider readiness; the consuming
|
|
531
535
|
Chat/Speech surface owns its visible mute and recovery state.
|
|
532
|
-
`fetchSTT(audioFile,signal)` propagates the caller-owned signal
|
|
533
|
-
|
|
536
|
+
`fetchSTT(audioFile,signal)` propagates the caller-owned signal, including the
|
|
537
|
+
native `Arcane.speech.transcribe(request, {signal})` route. The native signal
|
|
538
|
+
remains separate from the complete audio request; Core aborts are normalized
|
|
539
|
+
to `AbortError` with `ARCANE_AI_REQUEST_ABORTED`.
|
|
540
|
+
Provider routes accept a `Blob` or `File` directly and leave media decoding,
|
|
534
541
|
PCM normalization, and WAV construction to the selected shared provider;
|
|
535
542
|
delivery suppression is guaranteed after abort, while underlying provider-stop
|
|
536
543
|
claims remain limited to that provider's cancellation contract.
|
|
@@ -4168,7 +4175,9 @@ creating a profile or migrating saved data.
|
|
|
4168
4175
|
Exact exports: `arcaneThemeReady`, `bootstrapArcaneTheme`, `default`, and
|
|
4169
4176
|
`disposeArcaneThemeBootstrap`.
|
|
4170
4177
|
|
|
4171
|
-
`disposeArcaneThemeBootstrap()` removes
|
|
4178
|
+
`disposeArcaneThemeBootstrap()` removes bootstrap-owned subscriptions,
|
|
4179
|
+
native-window theme observers and listeners, and cancels its pending window
|
|
4180
|
+
request.
|
|
4172
4181
|
The cache is a presentation hint, not the authority for preferences or user
|
|
4173
4182
|
data. Preference loading and User readiness independently reconcile it; cache
|
|
4174
4183
|
failures are logged without blocking the page.
|
|
@@ -4178,6 +4187,29 @@ does not establish restoration before the first paint. Use the classic
|
|
|
4178
4187
|
[ThemePresentation head entry](#themepresentationjs) before CSS for that early
|
|
4179
4188
|
restoration. Neither entry imports User or starts its storage lifecycle.
|
|
4180
4189
|
|
|
4190
|
+
When a native host exposes `Arcane.window.setTheme`, the shared bootstrap
|
|
4191
|
+
samples the app body's inherited `--background` and `--text-color`. It resolves
|
|
4192
|
+
CSS variables, named colors, HSL and other browser-supported color forms through
|
|
4193
|
+
computed style. Modern color spaces use the browser's sRGB canvas conversion;
|
|
4194
|
+
the resolved alpha is retained separately, including translucency close to one.
|
|
4195
|
+
Authored styles remain unchanged. Missing semantic properties are omitted.
|
|
4196
|
+
|
|
4197
|
+
One listener on the shared `arcane-theme-change` owner, root/body presentation
|
|
4198
|
+
attribute observers, stylesheet-load events and device-color-scheme changes
|
|
4199
|
+
schedule samples. Identical channel values do not issue another request.
|
|
4200
|
+
Initial sampling and preference/profile reconciliation run independently of
|
|
4201
|
+
rendering and native completion. Page hide cancels the pending renderer wait;
|
|
4202
|
+
page restoration samples again. Print presentation is excluded. The host keeps
|
|
4203
|
+
its last accepted colors across navigation until the next document changes
|
|
4204
|
+
them. No additional theme bus, polling, storage or system-appearance mutation is
|
|
4205
|
+
introduced by this forwarding path.
|
|
4206
|
+
|
|
4207
|
+
Ordinary browsers and facades without the window method install no native
|
|
4208
|
+
sampler. An older host's unavailable-method response is recorded once in
|
|
4209
|
+
developer diagnostics and stops that sampler; genuine bridge failures retain
|
|
4210
|
+
their complete diagnostics. See the [current-window contract](core-client.md#current-window-theme)
|
|
4211
|
+
for per-field results, cancellation and actual adapter availability.
|
|
4212
|
+
|
|
4181
4213
|
### Availability and normalization
|
|
4182
4214
|
|
|
4183
4215
|
**Browser/native hybrid.** Theme state normalized; storage/native errors mixed. Transport: ThemeManager + Arcane.events. [Deep protocol details](protocols.md).
|
|
@@ -4563,6 +4563,12 @@ The object includes `importMap(options)`, which merges defaults with explicit
|
|
|
4563
4563
|
call options and refreshes every directly navigable descriptor-selected browser
|
|
4564
4564
|
document for one selected app. The equivalent generic route is
|
|
4565
4565
|
`execute('import-map', options)`.
|
|
4566
|
+
For a standalone root app with `pwa.enabled:false`, ordinary refresh removes
|
|
4567
|
+
marked SDK-generated PWA references from selected documents. An explicit
|
|
4568
|
+
`importMap({retireGeneratedPwa:true})` also retires the four standard root PWA
|
|
4569
|
+
outputs and matching older manifest references after the application owner
|
|
4570
|
+
confirms they are generated. See [disabled-PWA retirement](pwa.md#disable-source-pwa-generation-and-retire-generated-output)
|
|
4571
|
+
for the required source-selection adjustment and preserved content.
|
|
4566
4572
|
It also includes `upgrade(options)`, which performs the explicit installed-SDK
|
|
4567
4573
|
consumer upgrade described by `upgradeApplication()`, and
|
|
4568
4574
|
`updateCheck(options)`, which invokes `checkSdkUpdate()` once. Constructing the
|
|
@@ -4685,6 +4691,25 @@ documents through sequential writes and has no supported dry-run or
|
|
|
4685
4691
|
all-file transaction. An error or cancellation can leave completed writes in
|
|
4686
4692
|
place; rerun the operation after resolving the cause.
|
|
4687
4693
|
|
|
4694
|
+
For a standalone `appsRoot:'.'` app with `pwa.enabled:false`, ordinary refresh
|
|
4695
|
+
removes active generated registration scripts and matching manifest relationships
|
|
4696
|
+
marked `data-arcane-manifest`. Unmarked references and existing PWA files remain.
|
|
4697
|
+
Set `retireGeneratedPwa:true` only after confirming generated ownership of the
|
|
4698
|
+
matching root manifest references and all four standard outputs:
|
|
4699
|
+
`arcane.webmanifest`, `arcane-offline.json`, `arcane-sw.js` and `arcane-pwa.mjs`.
|
|
4700
|
+
Remove those generated outputs from required `package.include` entries first,
|
|
4701
|
+
and confirm that unselected documents no longer need them. The operation writes
|
|
4702
|
+
selected reference changes before deleting these files; its
|
|
4703
|
+
`import-map.root-files.completed` event reports actual removed paths in
|
|
4704
|
+
`retiredPwa`. Repeated retirement accepts already-absent output.
|
|
4705
|
+
|
|
4706
|
+
An omitted PWA record selects no retirement; an enabled record keeps normal
|
|
4707
|
+
generation. The option belongs only to this explicit import-map API route.
|
|
4708
|
+
Ordinary development refresh does not forward file-retirement authority, and
|
|
4709
|
+
there is no new CLI flag. Other files, unselected/inactive HTML, authored content
|
|
4710
|
+
and browser registrations, caches and saved data keep their existing ownership.
|
|
4711
|
+
See the complete [source PWA contract](pwa.md#disable-source-pwa-generation-and-retire-generated-output).
|
|
4712
|
+
|
|
4688
4713
|
The exact command `'upgrade'` dispatches `upgradeApplication(options)`. It is
|
|
4689
4714
|
external-workspace-only and runs that application's ordinary `npm upgrade`
|
|
4690
4715
|
command. It does not independently reconcile the installed SDK projection,
|
|
@@ -6899,6 +6924,18 @@ Import it from `arcane-os/core/client`. The result includes `runtime`, `events`,
|
|
|
6899
6924
|
`Error` and the existing `ai`, `environment`, `mail`, `speech`, `localAI`,
|
|
6900
6925
|
`ollama`, application, platform, storage and other host namespaces.
|
|
6901
6926
|
|
|
6927
|
+
`facade.speech.synthesize(request, {signal})` and
|
|
6928
|
+
`facade.speech.transcribe(request, {signal})` accept an optional `AbortSignal`
|
|
6929
|
+
through the same correlated request lifetime. Each complete request and existing
|
|
6930
|
+
180,000 ms timeout remain unchanged. A pre-aborted signal sends no speech
|
|
6931
|
+
request; an in-flight abort emits that request's `request.cancel`, rejects with
|
|
6932
|
+
`ARCANE_REQUEST_ABORTED` and leaves unrelated requests active. Late responses
|
|
6933
|
+
cannot settle the cancelled request. Actual native synthesis or transcription
|
|
6934
|
+
interruption belongs to the registered service and engine; this facade supplies
|
|
6935
|
+
no engine. The native routes of `AI.fetchTTS(payload, signal)` and
|
|
6936
|
+
`AI.fetchSTT(audio, signal)` forward their signals through these calls and
|
|
6937
|
+
normalize cancellation to `AbortError` with `ARCANE_AI_REQUEST_ABORTED`.
|
|
6938
|
+
|
|
6902
6939
|
### Availability and normalization
|
|
6903
6940
|
|
|
6904
6941
|
**Browser and native WebView JavaScript hosts with a Core client.** Creating the
|
|
@@ -7560,8 +7597,9 @@ import createDiarizationService from 'arcane-os/core/diarization';
|
|
|
7560
7597
|
|
|
7561
7598
|
### Overview
|
|
7562
7599
|
|
|
7563
|
-
Reads
|
|
7564
|
-
`--arcane-launch-config <path
|
|
7600
|
+
Reads the complete JSON object explicitly selected by
|
|
7601
|
+
`--arcane-launch-config <path>`, with an optional separately supplied native host
|
|
7602
|
+
state-directory default. It does not search for application configuration.
|
|
7565
7603
|
|
|
7566
7604
|
### Signature and result
|
|
7567
7605
|
|
|
@@ -7569,11 +7607,15 @@ Reads only the complete JSON object explicitly selected by
|
|
|
7569
7607
|
async readCoreLaunchContext({argv=process.argv.slice(2)}={})
|
|
7570
7608
|
```
|
|
7571
7609
|
|
|
7572
|
-
Import it from `arcane-os/core/host`.
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7610
|
+
Import it from `arcane-os/core/host`. `--arcane-host-state-root <directory>`
|
|
7611
|
+
supplies a `stateRoot` default; every field from the explicit launch JSON object
|
|
7612
|
+
then takes precedence unchanged, including a relative, null or other explicitly
|
|
7613
|
+
present `stateRoot`. With neither argument, the promise resolves to `{}`.
|
|
7614
|
+
A missing argument value, unreadable launch file, malformed JSON or non-object
|
|
7615
|
+
value rejects. Relative launch-file paths use the process working directory.
|
|
7616
|
+
The reader does not choose, resolve or validate the state directory, rewrite
|
|
7617
|
+
content, discover or migrate stored data, or mutate the environment. An
|
|
7618
|
+
application-selected `preferencesFile` remains a separate unchanged field.
|
|
7577
7619
|
|
|
7578
7620
|
```javascript
|
|
7579
7621
|
import {readCoreLaunchContext} from 'arcane-os/core/host';
|
|
@@ -7584,7 +7626,10 @@ const launchContext = await readCoreLaunchContext();
|
|
|
7584
7626
|
The generated entry supplies artifact-derived `appRoot`, then applies the whole
|
|
7585
7627
|
explicit context and passes the same object as every service factory's second
|
|
7586
7628
|
argument. Authored service options remain the first argument. Workspace/state
|
|
7587
|
-
locations and additional fields belong to the launcher/application.
|
|
7629
|
+
locations and additional fields belong to the launcher/application. Windows and
|
|
7630
|
+
Mac launchers forward their actual host-selected state directory through the
|
|
7631
|
+
separate argument; other composing hosts may use the same seam. This JavaScript
|
|
7632
|
+
contract does not establish a compiled host or matching release archive. See
|
|
7588
7633
|
[launch-time locations](core-native-packaging.md#launch-time-locations).
|
|
7589
7634
|
|
|
7590
7635
|
## createCoreLocalAIProvider()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.60.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",
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
"scripts": {
|
|
108
108
|
"test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
|
|
109
109
|
"test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
|
|
110
|
-
"test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.test.mjs test/contracts.test.mjs test/conversation-closing-report.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
|
|
111
|
-
"test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-decisions.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/continuous-voice-capture.test.mjs test/core-classic-source.test.mjs test/core-client.test.mjs test/core-host.test.mjs test/core-packaged-web.test.mjs test/core-runtime.test.mjs test/core-stdio.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/file-preview.test.mjs test/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/markdown-editor.test.mjs test/markdown-media.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/native-module-packaging.test.mjs test/native-module-resource-references.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/rendered-print.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/speech-playback.test.mjs test/site.test.mjs test/theme-manager.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/websocket-client-import-map.test.mjs test/websocket.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
|
|
110
|
+
"test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.test.mjs test/contracts.test.mjs test/conversation-closing-report.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/native-windows-icon.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
|
|
111
|
+
"test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-decisions.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/continuous-voice-capture.test.mjs test/core-classic-source.test.mjs test/core-client.test.mjs test/core-host.test.mjs test/core-packaged-web.test.mjs test/core-runtime.test.mjs test/core-stdio.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/file-preview.test.mjs test/import-map.test.mjs test/local-image-editing.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/markdown-editor.test.mjs test/markdown-media.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/native-module-packaging.test.mjs test/native-module-resource-references.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/rendered-print.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/speech-playback.test.mjs test/site.test.mjs test/theme-manager.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/websocket-client-import-map.test.mjs test/websocket.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
|
|
112
112
|
"test:integration": "node ./bin/arcane-test.mjs test/installed-package-runtime.test.mjs test/root-app-layout.test.mjs test/integrated-shared.test.mjs test/integrated-workspace.test.mjs test/mail-browser.test.mjs test/native-macos-provider.test.mjs test/native-plan.test.mjs test/native-portable-provider.test.mjs test/native-provider-loader.test.mjs test/npm-release.test.mjs test/release-bundle.test.mjs test/release-capability-smoke.test.mjs test/shared-payload-batch.test.mjs test/tarball.test.mjs test/browser-wasm-cpu.test.mjs test/wllama-webgpu-runtime.test.mjs",
|
|
113
113
|
"test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/html-import-registration.test.mjs test/html-import-packaged-script.test.mjs test/logging-regression.test.mjs test/markdown-speech.test.mjs test/prepared-speech.test.mjs test/native-provider-generation.test.mjs test/speech-queue-regression.test.mjs test/testing.test.mjs test/test-sets.test.mjs",
|
|
114
114
|
"check": "node tools/check-source.mjs && npm test",
|
|
@@ -4084,11 +4084,19 @@ class AI {
|
|
|
4084
4084
|
if(signal?.aborted){
|
|
4085
4085
|
throw normalizeAIRequestAbort(signal.reason);
|
|
4086
4086
|
}
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4087
|
+
let response;
|
|
4088
|
+
try{
|
|
4089
|
+
response=await nativeSpeech.transcribe({
|
|
4090
|
+
audioBase64:this.#arrayBufferToBase64(audioBytes),
|
|
4091
|
+
mimeType,
|
|
4092
|
+
model
|
|
4093
|
+
},{signal});
|
|
4094
|
+
}catch(error){
|
|
4095
|
+
if(isAIRequestAbort(error,signal)){
|
|
4096
|
+
throw normalizeAIRequestAbort(error);
|
|
4097
|
+
}
|
|
4098
|
+
throw error;
|
|
4099
|
+
}
|
|
4092
4100
|
if(signal?.aborted){
|
|
4093
4101
|
throw normalizeAIRequestAbort(signal.reason);
|
|
4094
4102
|
}
|
|
@@ -4138,13 +4146,21 @@ class AI {
|
|
|
4138
4146
|
const speed=is.finite(payload.speed)?payload.speed:this.voiceSpeed;
|
|
4139
4147
|
const nativeSpeech=this.#nativeSpeech(this.ttsService,'tts');
|
|
4140
4148
|
if(nativeSpeech){
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4149
|
+
let response;
|
|
4150
|
+
try{
|
|
4151
|
+
response=await nativeSpeech.synthesize({
|
|
4152
|
+
model,
|
|
4153
|
+
voice,
|
|
4154
|
+
input,
|
|
4155
|
+
responseFormat,
|
|
4156
|
+
speed
|
|
4157
|
+
},{signal});
|
|
4158
|
+
}catch(error){
|
|
4159
|
+
if(isAIRequestAbort(error,signal)){
|
|
4160
|
+
throw normalizeAIRequestAbort(error);
|
|
4161
|
+
}
|
|
4162
|
+
throw error;
|
|
4163
|
+
}
|
|
4148
4164
|
if(signal?.aborted){
|
|
4149
4165
|
throw normalizeAIRequestAbort(signal.reason);
|
|
4150
4166
|
}
|