arcane-os 0.7.0 → 0.7.2
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 +23 -0
- package/NOTICE +6 -11
- package/README.md +8 -8
- package/browser-runtime/ai/browser-device-settings.mjs +24 -20
- package/browser-runtime/ai/browser-speech-artifacts.mjs +86 -0
- package/browser-runtime/ai/browser-speech-providers.mjs +71 -7
- package/browser-runtime/ai/browser-wasm-llm-provider.mjs +15 -12
- package/browser-runtime/ai/browser-wllama-runtime.mjs +41 -2
- package/browser-runtime/ai/speech-worker-client.mjs +10 -2
- package/browser-runtime/ai/speech-worker-runtime.mjs +67 -3
- package/browser-runtime/ai/wllama/index.mjs +9 -9
- package/docs/architecture.md +1 -1
- package/docs/reference/ai/browser-speech.md +33 -15
- package/docs/reference/ai/browser-wasm.md +36 -28
- package/docs/reference/inventory/runtime-components.json +4 -4
- package/docs/reference/protocols.md +12 -5
- package/docs/reference/runtime-components.md +33 -22
- package/docs/reference/runtime-modules.md +7 -1
- package/docs/reference/sdk-api.md +5 -3
- package/package.json +1 -1
- package/runtime/arcane/components/browser-ai-setup.html +189 -179
- package/runtime/arcane/components/speech.html +34 -3
- package/runtime/arcane/components/voice-transcription.html +30 -3
- package/runtime/arcane/modules/ComponentContracts.js +86 -15
|
@@ -1592,6 +1592,52 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
|
|
|
1592
1592
|
if (engine) return status();
|
|
1593
1593
|
lifecycleReason = `${role}-load-started`;
|
|
1594
1594
|
let loadFailureReason = `${role}-worker-runtime-configuration-rejected`;
|
|
1595
|
+
let reporting = true;
|
|
1596
|
+
const completedFiles = new Set();
|
|
1597
|
+
const loadingFiles = new Set();
|
|
1598
|
+
function publishProgress(progress) {
|
|
1599
|
+
if (!reporting || signal?.aborted) return;
|
|
1600
|
+
send(
|
|
1601
|
+
{
|
|
1602
|
+
protocol: SPEECH_WORKER_PROTOCOL,
|
|
1603
|
+
id: request.id,
|
|
1604
|
+
type: 'progress',
|
|
1605
|
+
progress,
|
|
1606
|
+
}
|
|
1607
|
+
);
|
|
1608
|
+
}
|
|
1609
|
+
function reportModelProgress(detail) {
|
|
1610
|
+
if (!reporting || signal?.aborted) return;
|
|
1611
|
+
const file = detail?.file ?? null;
|
|
1612
|
+
if (file !== null) {
|
|
1613
|
+
const fileKey = `${detail.name ?? ''}/${file}`;
|
|
1614
|
+
if (detail?.status === 'done') {
|
|
1615
|
+
completedFiles.add(fileKey);
|
|
1616
|
+
loadingFiles.delete(fileKey);
|
|
1617
|
+
} else {
|
|
1618
|
+
loadingFiles.add(fileKey);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
const initializing = detail?.status === 'ready'
|
|
1622
|
+
|| (detail?.status === 'done' && loadingFiles.size === 0);
|
|
1623
|
+
const message = initializing
|
|
1624
|
+
? 'Preparing the speech model session'
|
|
1625
|
+
: detail?.status === 'done'
|
|
1626
|
+
? 'Loaded model file'
|
|
1627
|
+
: 'Loading model file';
|
|
1628
|
+
publishProgress(
|
|
1629
|
+
{
|
|
1630
|
+
phase: initializing ? 'initialize' : 'download',
|
|
1631
|
+
stage: 'model',
|
|
1632
|
+
message,
|
|
1633
|
+
file,
|
|
1634
|
+
completed: completedFiles.size,
|
|
1635
|
+
total: null,
|
|
1636
|
+
unit: 'files',
|
|
1637
|
+
detail,
|
|
1638
|
+
}
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1595
1641
|
try {
|
|
1596
1642
|
configuration = validateConfiguration(request.payload?.configuration, role);
|
|
1597
1643
|
const entry = configuration.runtime.files.find((file) =>
|
|
@@ -1605,6 +1651,15 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
|
|
|
1605
1651
|
});
|
|
1606
1652
|
}
|
|
1607
1653
|
loadFailureReason = `${role}-worker-runtime-import-rejected`;
|
|
1654
|
+
publishProgress(
|
|
1655
|
+
{
|
|
1656
|
+
phase: 'initialize',
|
|
1657
|
+
stage: 'runtime',
|
|
1658
|
+
message: 'Opening the speech runtime',
|
|
1659
|
+
file: entry.path,
|
|
1660
|
+
total: null,
|
|
1661
|
+
}
|
|
1662
|
+
);
|
|
1608
1663
|
const namespace = await import(entry.moduleUrl);
|
|
1609
1664
|
throwIfAborted(signal, `${role}-load-cancelled`);
|
|
1610
1665
|
restoreNamespace = configureRuntimeNamespace(
|
|
@@ -1614,10 +1669,17 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
|
|
|
1614
1669
|
environment.cache,
|
|
1615
1670
|
);
|
|
1616
1671
|
loadFailureReason = `${role}-worker-model-load-rejected`;
|
|
1617
|
-
|
|
1672
|
+
publishProgress(
|
|
1673
|
+
{
|
|
1674
|
+
phase: 'initialize',
|
|
1675
|
+
stage: 'model',
|
|
1676
|
+
message: `Initializing the speech model on ${configuration.execution?.device ?? 'wasm'}`,
|
|
1677
|
+
total: null,
|
|
1678
|
+
}
|
|
1679
|
+
);
|
|
1618
1680
|
engine = role === "stt"
|
|
1619
|
-
? await createWhisperEngine(namespace, configuration, signal,
|
|
1620
|
-
: await createKokoroEngine(namespace, configuration, signal,
|
|
1681
|
+
? await createWhisperEngine(namespace, configuration, signal, reportModelProgress)
|
|
1682
|
+
: await createKokoroEngine(namespace, configuration, signal, reportModelProgress);
|
|
1621
1683
|
lifecycleReason = `${role}-load-completed`;
|
|
1622
1684
|
return status();
|
|
1623
1685
|
} catch (error) {
|
|
@@ -1645,6 +1707,8 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
|
|
|
1645
1707
|
configuration = null;
|
|
1646
1708
|
lifecycleReason = failure.reason;
|
|
1647
1709
|
throw failure;
|
|
1710
|
+
} finally {
|
|
1711
|
+
reporting = false;
|
|
1648
1712
|
}
|
|
1649
1713
|
}
|
|
1650
1714
|
|
|
@@ -3490,7 +3490,9 @@ var Wllama = class {
|
|
|
3490
3490
|
}
|
|
3491
3491
|
|
|
3492
3492
|
const adapterAnchor = "if(adapter){WebGPU.Internals.jsObjectInsert(adapterPtr,adapter)";
|
|
3493
|
-
const adapterProjection = `if(adapter){(function arcaneRecordSelectedWebgpuAdapter(){const key="__arcaneWllamaWebgpuTelemetry";const previous=globalThis[key]??${emptyWorkerTelemetry};const info=adapter.info??{};const text=
|
|
3493
|
+
const adapterProjection = `if(adapter){(function arcaneRecordSelectedWebgpuAdapter(){const key="__arcaneWllamaWebgpuTelemetry";const previous=globalThis[key]??${emptyWorkerTelemetry};const info=adapter.info??{};const text = function preserveAdapterText(value) {
|
|
3494
|
+
return typeof value === 'string' ? value : '';
|
|
3495
|
+
};const next={selected:true,vendorId:null,vendor:text(info.vendor),architecture:text(info.architecture),deviceId:null,name:text(info.device),description:text(info.description),type:typeof info.type==="string"&&info.type?info.type:null,isFallbackAdapter:typeof info.isFallbackAdapter==="boolean"?info.isFallbackAdapter:typeof adapter.isFallbackAdapter==="boolean"?adapter.isFallbackAdapter:null};const conflicts=previous.adapter!==null&&JSON.stringify(previous.adapter)!==JSON.stringify(next);globalThis[key]={protocol:"${protocol}",adapter:previous.adapter??next,bufferCount:previous.bufferCount,bufferBytes:previous.bufferBytes,queueSubmissions:previous.queueSubmissions,commandBuffers:previous.commandBuffers,queueFenceRequests:previous.queueFenceRequests,queueFenceCompletions:previous.queueFenceCompletions,invalid:previous.invalid||conflicts}})();WebGPU.Internals.jsObjectInsert(adapterPtr,adapter)`;
|
|
3494
3496
|
WLLAMA_EMSCRIPTEN_CODE = replaceSingle(
|
|
3495
3497
|
WLLAMA_EMSCRIPTEN_CODE,
|
|
3496
3498
|
adapterAnchor,
|
|
@@ -3526,7 +3528,7 @@ var Wllama = class {
|
|
|
3526
3528
|
);
|
|
3527
3529
|
|
|
3528
3530
|
const workerAnchor = " if (verb === 'module.init') {";
|
|
3529
|
-
const workerProjection = ` if (verb === 'arcane.telemetry') {\n const observed = globalThis.__arcaneWllamaWebgpuTelemetry;\n const adapter = observed?.adapter?.selected === true ? {\n selected: true,\n vendorId: null,\n vendor: typeof observed.adapter.vendor === 'string' ? observed.adapter.vendor
|
|
3531
|
+
const workerProjection = ` if (verb === 'arcane.telemetry') {\n const observed = globalThis.__arcaneWllamaWebgpuTelemetry;\n const adapter = observed?.adapter?.selected === true ? {\n selected: true,\n vendorId: null,\n vendor: typeof observed.adapter.vendor === 'string' ? observed.adapter.vendor : '',\n architecture: typeof observed.adapter.architecture === 'string' ? observed.adapter.architecture : '',\n deviceId: null,\n name: typeof observed.adapter.name === 'string' ? observed.adapter.name : '',\n description: typeof observed.adapter.description === 'string' ? observed.adapter.description : '',\n type: typeof observed.adapter.type === 'string' ? observed.adapter.type : null,\n isFallbackAdapter: typeof observed.adapter.isFallbackAdapter === 'boolean' ? observed.adapter.isFallbackAdapter : null,\n } : null;\n msg({\n callbackId,\n result: {\n protocol: '${protocol}',\n adapter,\n bufferCount: Number.isSafeInteger(observed?.bufferCount) ? observed.bufferCount : 0,\n bufferBytes: Number.isSafeInteger(observed?.bufferBytes) ? observed.bufferBytes : 0,\n queueSubmissions: Number.isSafeInteger(observed?.queueSubmissions) ? observed.queueSubmissions : 0,\n commandBuffers: Number.isSafeInteger(observed?.commandBuffers) ? observed.commandBuffers : 0,\n queueFenceRequests: Number.isSafeInteger(observed?.queueFenceRequests) ? observed.queueFenceRequests : 0,\n queueFenceCompletions: Number.isSafeInteger(observed?.queueFenceCompletions) ? observed.queueFenceCompletions : 0,\n invalid: observed?.invalid === true,\n },\n });\n return;\n }\n\n${workerAnchor}`;
|
|
3530
3532
|
LLAMA_CPP_WORKER_CODE = replaceSingle(
|
|
3531
3533
|
LLAMA_CPP_WORKER_CODE,
|
|
3532
3534
|
workerAnchor,
|
|
@@ -3539,7 +3541,7 @@ var Wllama = class {
|
|
|
3539
3541
|
return Number.isSafeInteger(candidate) && candidate >= 0 ? candidate : 0;
|
|
3540
3542
|
}
|
|
3541
3543
|
function adapterText(candidate) {
|
|
3542
|
-
return typeof candidate === "string"
|
|
3544
|
+
return typeof candidate === "string" ? candidate : "";
|
|
3543
3545
|
}
|
|
3544
3546
|
const rawAdapter = value?.adapter;
|
|
3545
3547
|
const adapterInvalid = rawAdapter !== undefined && rawAdapter !== null && (
|
|
@@ -3547,16 +3549,12 @@ var Wllama = class {
|
|
|
3547
3549
|
|| rawAdapter.selected !== true
|
|
3548
3550
|
|| rawAdapter.vendorId !== null
|
|
3549
3551
|
|| typeof rawAdapter.vendor !== "string"
|
|
3550
|
-
|| rawAdapter.vendor.length > 256
|
|
3551
3552
|
|| typeof rawAdapter.architecture !== "string"
|
|
3552
|
-
|| rawAdapter.architecture.length > 256
|
|
3553
3553
|
|| rawAdapter.deviceId !== null
|
|
3554
3554
|
|| typeof rawAdapter.name !== "string"
|
|
3555
|
-
|| rawAdapter.name.length > 256
|
|
3556
3555
|
|| typeof rawAdapter.description !== "string"
|
|
3557
|
-
|| rawAdapter.description.length > 256
|
|
3558
3556
|
);
|
|
3559
|
-
const adapter = rawAdapter?.selected === true ?
|
|
3557
|
+
const adapter = rawAdapter?.selected === true ? {
|
|
3560
3558
|
selected: true,
|
|
3561
3559
|
vendorId: null,
|
|
3562
3560
|
vendor: adapterText(rawAdapter.vendor),
|
|
@@ -3564,7 +3562,9 @@ var Wllama = class {
|
|
|
3564
3562
|
deviceId: null,
|
|
3565
3563
|
name: adapterText(rawAdapter.name),
|
|
3566
3564
|
description: adapterText(rawAdapter.description),
|
|
3567
|
-
|
|
3565
|
+
type: typeof rawAdapter.type === "string" ? rawAdapter.type : null,
|
|
3566
|
+
isFallbackAdapter: typeof rawAdapter.isFallbackAdapter === "boolean" ? rawAdapter.isFallbackAdapter : null,
|
|
3567
|
+
} : null;
|
|
3568
3568
|
return Object.freeze({
|
|
3569
3569
|
protocol,
|
|
3570
3570
|
adapter,
|
package/docs/architecture.md
CHANGED
|
@@ -279,7 +279,7 @@ paths are withheld from the native provider. The provider copies the complete
|
|
|
279
279
|
selected release rather than accepting an unrelated source path. Verification
|
|
280
280
|
is a separate explicit operation for a selected release artifact.
|
|
281
281
|
|
|
282
|
-
The SDK `0.7.
|
|
282
|
+
The SDK `0.7.2` runtime requires Arcane `0.8.12` or newer. Compatibility
|
|
283
283
|
is contractual rather than exact-version pinning: the prepared Core must meet
|
|
284
284
|
the highest minimum declared by the runtime, selected app, and bundled app
|
|
285
285
|
dependencies; keep each app's Arcane protocol generation; and provide every
|
|
@@ -144,28 +144,34 @@ name. It does not load a model or create a GPU device or WebNN context:
|
|
|
144
144
|
</html-import>
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
**NPU setup** provides a **Copy NPU flag address** button regardless of WebNN
|
|
148
|
+
availability, with one short explanation. Chrome uses
|
|
148
149
|
`chrome://flags/#web-machine-learning-neural-network`; Edge uses
|
|
149
150
|
`edge://flags/#web-machine-learning-neural-network`. Unrecognized browsers
|
|
150
|
-
receive explicit Chrome and Edge choices.
|
|
151
|
-
|
|
151
|
+
receive explicit Chrome and Edge choices. A failed copy shows the complete
|
|
152
|
+
address as selectable text; the component does not open internal browser pages.
|
|
152
153
|
The [ONNX Runtime WebNN guide](https://onnxruntime.ai/docs/tutorials/web/ep-webnn.html)
|
|
153
154
|
documents the **Enables WebNN API** flag and model/operator requirements.
|
|
154
155
|
|
|
155
|
-
The **GPU performance** section shows adapter
|
|
156
|
-
|
|
156
|
+
The **GPU performance** section shows a short adapter status and a **Copy GPU
|
|
157
|
+
flag address** button on desktop Windows Chromium browsers. The button remains
|
|
158
|
+
available for every adapter class, unavailable API, or detection failure. One
|
|
159
|
+
shared instruction explains pasting, enabling, saving work, and relaunching. Identified
|
|
157
160
|
Chrome uses `chrome://flags/#force-high-performance-gpu`; other recognized
|
|
158
|
-
Chromium browsers use their corresponding internal scheme. **
|
|
159
|
-
|
|
161
|
+
Chromium browsers use their corresponding internal scheme. **Refresh**
|
|
162
|
+
requests a new availability result; concurrent
|
|
160
163
|
requests share the pending operation. The public `checkGpu()` method provides
|
|
161
164
|
the same promise, while `refresh()` remains a synchronous API-presence and
|
|
162
165
|
settings update. Component readiness does not wait for adapter detection.
|
|
163
166
|
|
|
164
167
|
Adapter selection uses `powerPreference: "high-performance"` as a hint, not proof
|
|
165
|
-
of the selected GPU's performance or the flag's current state.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
is
|
|
168
|
+
of the selected GPU's performance or the flag's current state. When the browser
|
|
169
|
+
explicitly reports a discrete GPU, Profile says **Already using the performance
|
|
170
|
+
GPU.** Explicit integrated or software/fallback
|
|
171
|
+
metadata is reported as such. Missing type metadata shows **GPU available.**
|
|
172
|
+
and leaves performance selection unconfirmed; a vendor name is not a GPU
|
|
173
|
+
classification. The component cannot read the browser flag or prove that a
|
|
174
|
+
model is executing on the adapter. See the
|
|
169
175
|
[component contract](../runtime-components.md#browser-ai-setuphtml) for result
|
|
170
176
|
fields, failure handling, and disposal behavior.
|
|
171
177
|
|
|
@@ -1204,10 +1210,22 @@ that accelerator kernels overlap, or that generated speech is correct. WebNN
|
|
|
1204
1210
|
may execute unsupported operations through WASM. A security field is absent
|
|
1205
1211
|
in ordinary mode.
|
|
1206
1212
|
|
|
1207
|
-
The provider/2 load context accepts an optional progress callback
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1213
|
+
The provider/2 load context accepts an optional `progress` callback. Speech
|
|
1214
|
+
artifact preparation and upstream model loading publish records through that
|
|
1215
|
+
callback and the shared sticky AI runtime state. Records include `phase`,
|
|
1216
|
+
`stage`, `message`, the current `file` when available, and `elapsedMs`.
|
|
1217
|
+
Known artifact inventories report `completed`, `total`, and `unit:'files'`.
|
|
1218
|
+
Upstream model files are discovered during loading, so their total remains
|
|
1219
|
+
`null` while completed files are counted. Remaining TTS pool initialization
|
|
1220
|
+
reports completed model sessions. Consumers use an indeterminate progress bar
|
|
1221
|
+
when no final total is known; transfer quantities do not determine this display.
|
|
1222
|
+
|
|
1223
|
+
The Worker sends intermediate `{protocol,id,type:'progress',progress}` messages
|
|
1224
|
+
for its active load request. They do not settle the request; the ordinary final
|
|
1225
|
+
response still owns completion or failure. Complete upstream callback content
|
|
1226
|
+
remains in the adjacent `detail` field for diagnostics. Compatible observers
|
|
1227
|
+
receive the latest progress when joining an active load, and cancelled,
|
|
1228
|
+
superseded, or settled loads stop publishing progress.
|
|
1211
1229
|
|
|
1212
1230
|
Compatible concurrent loads share one underlying preparation and pool load
|
|
1213
1231
|
while each caller retains its own cancellation signal. One observer cannot
|
|
@@ -187,34 +187,42 @@ Applications remain responsible for model selection and license compliance.
|
|
|
187
187
|
cannot download. Source downloads use CORS, omit credentials and referrer,
|
|
188
188
|
disable HTTP caching, and honor `AbortSignal`.
|
|
189
189
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
the
|
|
194
|
-
|
|
195
|
-
an
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
190
|
+
After a model loads, its existing Worker reports the adapter it selected.
|
|
191
|
+
The runtime retains that adapter in `evidence().webgpu.adapter`, including
|
|
192
|
+
optional browser-reported `type` and `isFallbackAdapter` fields. This reads
|
|
193
|
+
the loaded Worker's metadata once; it does not request another adapter.
|
|
194
|
+
Missing fields remain unknown. Cancellation also cancels the metadata wait;
|
|
195
|
+
an unavailable observation is logged without rejecting an otherwise loaded model.
|
|
196
|
+
|
|
197
|
+
On Windows desktop Chromium browsers, an explicitly reported integrated GPU,
|
|
198
|
+
CPU, or fallback adapter triggers one GPU-only browser alert per page session.
|
|
199
|
+
The alert names the selected adapter and **Force High Performance GPU**
|
|
200
|
+
(`#force-high-performance-gpu`), conditional on the computer also having a
|
|
201
|
+
discrete GPU. It contains the address to paste manually and asks the user to
|
|
202
|
+
save their work and completely close and reopen the browser after changing
|
|
203
|
+
the flag. It does not open a window or navigate to an internal browser page.
|
|
204
|
+
Discrete adapters and unknown adapter classes do not trigger the alert.
|
|
205
|
+
|
|
206
|
+
An identified Chrome, Microsoft Edge, Brave, Opera, or Vivaldi receives its own
|
|
207
|
+
`chrome://`, `edge://`, `brave://`, `opera://`, or `vivaldi://` flags address.
|
|
208
|
+
Other detected Chromium browsers receive
|
|
209
|
+
`about://flags/#force-high-performance-gpu` with neutral browser wording.
|
|
210
|
+
Only the current browser's address appears. Firefox, Safari, non-Windows
|
|
211
|
+
platforms, and mobile browsers receive no flag notice. The alert contains no
|
|
212
|
+
NPU guidance or unrelated flags. The Profile `browser-ai-setup` component
|
|
213
|
+
provides Copy controls for its browser addresses.
|
|
214
|
+
|
|
215
|
+
An adapter vendor or name does not establish its GPU class, and
|
|
216
|
+
`powerPreference: "high-performance"` is a request hint rather than proof of
|
|
217
|
+
the selected hardware. Chromium's optional adapter `type` is a
|
|
218
|
+
[developer feature](https://developer.chrome.com/docs/web-platform/webgpu/developer-features);
|
|
219
|
+
the standard API does not always expose integrated or discrete classification.
|
|
220
|
+
The Profile says **Already using the performance GPU.** for an explicitly
|
|
221
|
+
reported discrete GPU and hides performance flag advice. Missing classification
|
|
222
|
+
shows **GPU available.** without flag advice and remains unconfirmed.
|
|
223
|
+
The browser does not expose the flag's current value or a reliable machine-wide
|
|
224
|
+
GPU count, and a discrete adapter does not prove it is the fastest available.
|
|
225
|
+
See [Chrome's GPU selection guidance](https://developer.chrome.com/docs/web-platform/webgpu/troubleshooting-tips#webgpu_is_slower_than_webgl).
|
|
218
226
|
|
|
219
227
|
## Streaming, cancellation, and tools
|
|
220
228
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"repository": "https://github.com/TheWizardNexus/arcane-os-sdk.git",
|
|
6
6
|
"branch": "main",
|
|
7
7
|
"path": "runtime/arcane/components",
|
|
8
|
-
"sdkVersion": "0.
|
|
8
|
+
"sdkVersion": "0.7.2"
|
|
9
9
|
},
|
|
10
10
|
"componentCount": 40,
|
|
11
11
|
"loader": "/arcane/modules/HTMLImport.js",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
{
|
|
80
80
|
"file": "runtime/arcane/components/browser-ai-setup.html",
|
|
81
81
|
"name": "browser-ai-setup.html",
|
|
82
|
-
"purpose": "Displays browser API
|
|
82
|
+
"purpose": "Displays browser API availability, browser-reported GPU class, and copyable NPU/GPU flags addresses.",
|
|
83
83
|
"methods": [
|
|
84
84
|
"refresh()",
|
|
85
85
|
"checkGpu()",
|
|
@@ -97,8 +97,8 @@
|
|
|
97
97
|
"arcane-os/event-manager"
|
|
98
98
|
],
|
|
99
99
|
"availability": "Browser and supported native WebViews",
|
|
100
|
-
"transport": "HTMLImport + DOM;
|
|
101
|
-
"normalization": "API presence, adapter availability, and
|
|
100
|
+
"transport": "HTMLImport + DOM; Clipboard API and WebGPU adapter request. Settings addresses use Copy controls and appear as text if copying fails; open() copies the NPU address without navigation or an alert.",
|
|
101
|
+
"normalization": "API presence, adapter availability, explicit browser GPU class, and copy instructions normalized. Supported browser NPU and GPU flag copy controls remain available regardless of API availability, adapter class, or detection failure. A reported discrete GPU shows Already using the performance GPU. Absent type metadata shows GPU available and leaves performance selection unconfirmed. Mounting starts one adapter request; checkGpu() coalesces concurrent calls, while refresh() remains synchronous. No GPU device, model, or WebNN context is created. Adapter metadata does not establish browser flag state, the fastest physical GPU, or another page's model execution."
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
104
|
"file": "runtime/arcane/components/calculator.html",
|
|
@@ -380,8 +380,13 @@ the module declares a shadowing binding with the same name. Explicit
|
|
|
380
380
|
`globalThis` or `self` calls continue through the materialized-file router.
|
|
381
381
|
|
|
382
382
|
The speech Worker uses its ordinary global Worker message boundary directly for
|
|
383
|
-
requests, results, errors, and cancellation. It creates no private
|
|
384
|
-
`MessageChannel
|
|
383
|
+
requests, progress, results, errors, and cancellation. It creates no private
|
|
384
|
+
`MessageChannel`. During loading, `{protocol,id,type:'progress',progress}`
|
|
385
|
+
messages retain the active request id without settling its pending result.
|
|
386
|
+
Progress records describe the current phase, stage, message, file, and completed
|
|
387
|
+
file count with `total:null` for dynamically discovered model files. Complete
|
|
388
|
+
upstream callback content remains in the adjacent `detail` field. The ordinary
|
|
389
|
+
final success or failure envelope ends the request and its progress stream.
|
|
385
390
|
|
|
386
391
|
Worker operations use `arcane-ai-speech-worker/1`. The public Worker client
|
|
387
392
|
supports `load`, `use`, `status`, `unload`, and `dispose`; the transport host
|
|
@@ -459,9 +464,11 @@ while the loaded provider remains ready.
|
|
|
459
464
|
Speech failure neither disables text chat nor retries through another local,
|
|
460
465
|
native, or cloud provider. The provider/Worker layer is event-neutral: it
|
|
461
466
|
exposes promises, `AbortSignal`, and precise lifecycle/status records, but owns
|
|
462
|
-
no event bus
|
|
463
|
-
|
|
464
|
-
|
|
467
|
+
no event bus. The provider/2 load context accepts an optional `progress`
|
|
468
|
+
callback that receives artifact preparation, upstream model loading, and session
|
|
469
|
+
initialization records. Compatible concurrent observers share one load and
|
|
470
|
+
receive its current progress; cancelling one observer leaves the others active.
|
|
471
|
+
The shared AI runtime projects those records into sticky role state.
|
|
465
472
|
|
|
466
473
|
### Persistent chat and document context
|
|
467
474
|
|
|
@@ -60,7 +60,7 @@ appropriate.
|
|
|
60
60
|
| --- | --- | --- | --- | --- |
|
|
61
61
|
| [`app-bar.html`](#app-barhtml) | Responsive application navigation, route state, status, and trailing actions. | `setNavigation()`<br>`setActiveRoute()`<br>`setStatus()`<br>`refresh()`<br>`destroy()` | `app-bar-ready` | DOM-normalized |
|
|
62
62
|
| [`assistant-panel.html`](#assistant-panelhtml) | Reusable assistant drawer, message area, composer, pending/streaming/empty/error state, and actions. | `open()`<br>`close()`<br>`toggle()`<br>`send()`<br>`clear()`<br>`setState()`<br>`focusComposer()`<br>`scrollToEnd()`<br>`destroy()` | `assistant-ready`<br>`assistant-opened`<br>`assistant-closed`<br>`assistant-send`<br>`assistant-clear` | DOM-normalized; caller/provider results remain external |
|
|
63
|
-
| [`browser-ai-setup.html`](#browser-ai-setuphtml) | Browser API
|
|
63
|
+
| [`browser-ai-setup.html`](#browser-ai-setuphtml) | Browser API availability, reported GPU class, and copyable NPU/GPU settings addresses. | `refresh()`<br>`checkGpu()`<br>`open()`<br>`destroy()`<br>`ready` | `browser-ai-setup-ready` | Browser-reported adapter class; browser flag state and model execution remain browser-owned |
|
|
64
64
|
| [`calculator.html`](#calculatorhtml) | Calculator keypad and result/error event surface backed by CalculatorEngine. | `calculate()`<br>`destroy()` | `calculator-ready`<br>`calculation-complete`<br>`calculation-error` | Normalized Calculation/error events |
|
|
65
65
|
| [`chart.html`](#charthtml) | Accessible uPlot line, area, or point chart with normalized options and rows. | `configure()`<br>`populate()`<br>`setData()`<br>`addData()`<br>`update()`<br>`destroy()` | `chart-ready`<br>`chart-remove` | Options/rows normalized; uPlot rendering is vendor-native |
|
|
66
66
|
| [`chat.html`](#chathtml) | Shared chat, visible selected-model activation request, file upload, streaming, structural tool settlement, speech, language, availability, and conversation-timebox surface. | `streamMessage()`<br>`setMessageProgress()`<br>`setAIAvailability()`<br>`setInitialSpeechMuted()`<br>`setConversationComplete()`<br>`bindConversationTimebox()`<br>`bindSession()`<br>`submitMessage()`<br>`submitToolResult()`<br>`submitToolResults()`<br>`sendMessage()`<br>`languageChanged()`<br>`requestAIActivation()`<br>`destroy()` | `chat-ready`<br>`chat-session-bound`<br>`chat-session-message`<br>`chat-session-error`<br>`chat-send-message`<br>`chat-send-error`<br>`chat-file-uploaded`<br>`chat-file-upload-error`<br>`chat-language-changed`<br>`chat-language-change-error`<br>`chat-ai-activation-request`<br>`chat-ai-activation-error`<br>`chat-speech-synthesis-error`<br>`conversation-timebox-error` | UI/runtime state, explicit user activation intent, and honest structural-call settlement normalized; AI/storage/media behavior mixed |
|
|
@@ -158,14 +158,16 @@ Slots: `title`, `subtitle`, `identity`, `messages/message`, `composer`, `actions
|
|
|
158
158
|
|
|
159
159
|
### Overview
|
|
160
160
|
|
|
161
|
-
Displays
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
Chromium browsers also receive the matching Force High Performance GPU link,
|
|
161
|
+
Displays a short WebNN availability status and the detected WebGPU adapter.
|
|
162
|
+
Chrome and Edge receive a **Copy NPU flag address** button for their own browser;
|
|
163
|
+
unidentified browsers show both choices. Desktop Windows Chromium browsers
|
|
164
|
+
receive a **Copy GPU flag address** button for the matching browser,
|
|
166
165
|
including `chrome://flags/#force-high-performance-gpu` for identified Chrome.
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
Both controls remain available regardless of API availability, adapter class,
|
|
167
|
+
or detection failure. Each flag has one short explanation, followed by a shared
|
|
168
|
+
paste, enable, save, and relaunch instruction.
|
|
169
|
+
Settings addresses use Copy controls and appear as selectable text if copying
|
|
170
|
+
fails. The component does not attempt navigation to internal browser pages.
|
|
169
171
|
|
|
170
172
|
### Public surface
|
|
171
173
|
|
|
@@ -184,26 +186,31 @@ calls share the pending promise. The component requests an adapter with the
|
|
|
184
186
|
`"high-performance"` power-preference hint; it does not create a GPU device or
|
|
185
187
|
load a model. An unavailable result contains `available: false` and a `reason`
|
|
186
188
|
of `"api-unavailable"` or `"adapter-unavailable"`. An available result contains
|
|
187
|
-
`available: true`, the reported adapter `name`,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
`available: true`, the reported adapter `name`, `isFallbackAdapter` as a boolean
|
|
190
|
+
or `null`, `adapterType` as the browser's string or `null`, and
|
|
191
|
+
`performanceStatus`: `"discrete"`, `"integrated"`, `"fallback"`, or `"unknown"`.
|
|
192
|
+
Only the explicit browser type or fallback field establishes that status;
|
|
193
|
+
vendor names and the requested power preference do not. A discrete result
|
|
194
|
+
shows **Already using the performance GPU.** An unknown class shows **GPU available.**
|
|
195
|
+
and leaves performance selection unconfirmed. Adapter selection does not
|
|
196
|
+
prove that a browser flag is enabled, that the fastest GPU was selected, or that
|
|
197
|
+
a model is using it. Failure is displayed and logged, and the promise
|
|
191
198
|
resolves to `false`; destruction also yields `false` and suppresses late UI
|
|
192
199
|
updates.
|
|
193
200
|
|
|
194
|
-
Mounting starts one `checkGpu()` operation. **
|
|
195
|
-
|
|
201
|
+
Mounting starts one `checkGpu()` operation. **Refresh** calls both `refresh()`
|
|
202
|
+
and `checkGpu()`. Calling
|
|
196
203
|
`refresh()` directly remains synchronous and does not request an adapter.
|
|
197
204
|
`ready` and `browser-ai-setup-ready` describe component setup, which can complete
|
|
198
205
|
while adapter detection is still pending.
|
|
199
206
|
|
|
200
|
-
`open()`
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
+
The retained `open(browserId?)` method now copies the matching NPU flags address
|
|
208
|
+
instead of navigating or showing an alert. Pass `"chrome"` or `"edge"` to choose
|
|
209
|
+
explicitly and invoke it from a user action. It returns a promise resolving to
|
|
210
|
+
`true` only after clipboard success, or `false` for destruction, an unsupported
|
|
211
|
+
target, or copy failure. The complete address remains selectable if clipboard
|
|
212
|
+
access fails. On-screen instructions explain pasting it into the address bar,
|
|
213
|
+
enabling WebNN, and relaunching.
|
|
207
214
|
|
|
208
215
|
`destroy()` aborts owned listeners, disposes the event source, marks `ready`
|
|
209
216
|
false, and suppresses UI updates from pending clipboard and adapter operations.
|
|
@@ -1497,7 +1504,11 @@ For a selected `unloaded`, `loading`, `unloading`, or `error` role, the componen
|
|
|
1497
1504
|
keeps recording Start disabled and presents the same keyboard-operable Start
|
|
1498
1505
|
transcription/Try again or Cancel loading control as `speech.html`. Both use the
|
|
1499
1506
|
shared `createSTTActivationController()` contract. User operation emits the
|
|
1500
|
-
cancelable `speech-stt-activation-request` event with mutable complete `{intent,state}
|
|
1507
|
+
cancelable `speech-stt-activation-request` event with mutable complete `{intent,state}`.
|
|
1508
|
+
During loading, both controls show a native progress bar and the current
|
|
1509
|
+
preparation, download, or initialization message with the current file and
|
|
1510
|
+
reported elapsed time. Unknown totals remain indeterminate. In `speech.html`,
|
|
1511
|
+
prior local status stays visible alongside the loading status. The activation event's
|
|
1501
1512
|
`preventDefault()` suppresses the callback. The default
|
|
1502
1513
|
`requestSTTActivation(intent)` publishes the mutable
|
|
1503
1514
|
`{role:'stt',action:'load'|'unload',reason:'user'}` intent. Callback failure emits
|
|
@@ -1417,7 +1417,7 @@ behavior for chart, dashboard, Markdown, and voice components.
|
|
|
1417
1417
|
### Public surface
|
|
1418
1418
|
|
|
1419
1419
|
Constant sets plus normalization, formatting, and explicit STT activation
|
|
1420
|
-
helpers. `createSTTActivationController({host,button,onChange,EventClass=CustomEvent})`
|
|
1420
|
+
helpers. `createSTTActivationController({host,button,progress=null,onChange,EventClass=CustomEvent})`
|
|
1421
1421
|
consumes only normalized
|
|
1422
1422
|
[`AIRuntimeState`](#airuntimestatejs) `stt` role records. Its mutable controller
|
|
1423
1423
|
exposes `action`, `error`, `label`, `pending`, `selected`, `status`, `title`, and
|
|
@@ -1428,6 +1428,12 @@ exposes `action`, `error`, `label`, `pending`, `selected`, `status`, `title`, an
|
|
|
1428
1428
|
callers use the default `CustomEvent`; non-DOM callers must inject a compatible
|
|
1429
1429
|
`EventClass` constructor.
|
|
1430
1430
|
|
|
1431
|
+
An optional native `progress` element presents the active loading phase. Known
|
|
1432
|
+
file or session totals produce determinate progress; an unknown total remains
|
|
1433
|
+
indeterminate. The shared status includes the complete loading message, current
|
|
1434
|
+
file, completion count, and reported elapsed time. Terminal state and destruction
|
|
1435
|
+
clear the loading display without starting any provider work.
|
|
1436
|
+
|
|
1431
1437
|
`request('load'|'unload')` emits the cancelable
|
|
1432
1438
|
`speech-stt-activation-request` event with mutable `{intent,state}` before it
|
|
1433
1439
|
invokes `host.requestSTTActivation(intent)`. Callback failure emits
|
|
@@ -6395,9 +6395,11 @@ and materializes object URLs, then returns
|
|
|
6395
6395
|
`{cache,runtime,model,release}`. Call `release()` when the Worker no longer
|
|
6396
6396
|
needs those URLs. `offline:true` never fetches and rejects a miss with
|
|
6397
6397
|
`ARCANE_AI_ARTIFACT_OFFLINE_MISS`. `remove(authority)` deletes that exact
|
|
6398
|
-
authority's files and selection metadata. `onProgress`
|
|
6399
|
-
|
|
6400
|
-
|
|
6398
|
+
authority's files and selection metadata. Optional `onProgress` receives
|
|
6399
|
+
preparation and download records with `phase`, `stage`, `message`, and the
|
|
6400
|
+
current `file` when available. File operations report actual `completed` and
|
|
6401
|
+
`total` inventory counts with `unit:'files'`; module preparation uses
|
|
6402
|
+
`total:null`. Cancellation stops progress along with the owning operation.
|
|
6401
6403
|
|
|
6402
6404
|
### Availability and normalization
|
|
6403
6405
|
|
package/package.json
CHANGED