arcane-os 0.5.9 → 0.5.11
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 +28 -0
- package/README.md +117 -26
- package/browser-runtime/ai/browser-speech-providers.mjs +1 -1
- package/browser-runtime/ai/browser-wasm-llm-provider.mjs +63 -39
- package/docs/architecture.md +303 -0
- package/docs/compatibility.md +38 -0
- package/docs/event-manager.md +263 -0
- package/docs/platform-targets.md +104 -0
- package/docs/publishing.md +126 -0
- package/docs/reference/README.md +206 -0
- package/docs/reference/ai/browser-speech.md +813 -0
- package/docs/reference/ai/browser-wasm.md +637 -0
- package/docs/reference/ai/twin-cloud.md +156 -0
- package/docs/reference/arcane-ollama.md +288 -0
- package/docs/reference/availability-and-normalization.md +224 -0
- package/docs/reference/behavioral-testing.md +129 -0
- package/docs/reference/cli.md +820 -0
- package/docs/reference/core/README.md +61 -0
- package/docs/reference/core/arcane-ai-contracts.md +907 -0
- package/docs/reference/core/arcane-api.md +601 -0
- package/docs/reference/core/arcane-entities.md +59 -0
- package/docs/reference/core/arcane-events.md +134 -0
- package/docs/reference/core/ollama-module.md +181 -0
- package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +1909 -0
- package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +1057 -0
- package/docs/reference/core/reference/arcane-api/core-and-events.md +320 -0
- package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +610 -0
- package/docs/reference/core/reference/arcane-api/namespaces.md +1157 -0
- package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +1423 -0
- package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +315 -0
- package/docs/reference/event-manager.md +1409 -0
- package/docs/reference/inventory/package-api.json +3194 -0
- package/docs/reference/inventory/runtime-components.json +1015 -0
- package/docs/reference/inventory/runtime-entities.json +25 -0
- package/docs/reference/inventory/runtime-modules.json +1367 -0
- package/docs/reference/mail.md +309 -0
- package/docs/reference/protocols.md +749 -0
- package/docs/reference/runtime-components.md +1529 -0
- package/docs/reference/runtime-entities.md +305 -0
- package/docs/reference/runtime-modules.md +3275 -0
- package/docs/reference/sdk-api.md +6733 -0
- package/docs/roadmap.md +79 -0
- package/docs/work-amplification.md +66 -0
- package/examples/wasm-ai-demo/README.md +80 -0
- package/examples/wasm-ai-demo/app.js +787 -0
- package/examples/wasm-ai-demo/index.html +343 -0
- package/examples/wasm-ai-demo/profile-tools.js +217 -0
- package/examples/wasm-ai-demo/profiles/BOSS.Modelfile +106 -0
- package/examples/wasm-ai-demo/profiles/PreCrisis.Modelfile +693 -0
- package/examples/wasm-ai-demo/rag/boss-library.json +3006 -0
- package/examples/wasm-ai-demo/rag.js +295 -0
- package/examples/wasm-ai-demo/server.mjs +71 -0
- package/package.json +11 -2
- package/runtime/arcane/modules/AI.js +1 -1
- package/runtime/arcane/modules/AIProviderRuntime.js +26 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.11
|
|
4
|
+
|
|
5
|
+
- Default browser Kokoro TTS to four concurrent synthesis slots in both the
|
|
6
|
+
high-level AI configuration and direct provider. Explicit capacities 1–4
|
|
7
|
+
remain supported; LLM and Whisper/STT capacity remains one. Overflow waits
|
|
8
|
+
in the provider-neutral FIFO queue, and playback retains exact input order
|
|
9
|
+
with contiguous AudioContext scheduling. Each slot owns a Worker/model
|
|
10
|
+
session, trading memory for latency without promising physical GPU overlap.
|
|
11
|
+
- Add opt-in live execution details through
|
|
12
|
+
`ai.providerRuntime.status('tts', {execution: true}).execution`, including
|
|
13
|
+
requested and selected device, capacity, and active requests. Existing
|
|
14
|
+
no-option status snapshots keep their behavior; automatic WASM fallback is
|
|
15
|
+
observable without private provider access.
|
|
16
|
+
- Front-load basic browser speech and TWiN examples, document exact saved
|
|
17
|
+
preference migration, refresh current reference inventories and generated
|
|
18
|
+
site content, and include maintained `docs/` and the browser AI demo source
|
|
19
|
+
in the installed package. Documentation deployment now uses an explicit
|
|
20
|
+
selected-main Pages workflow.
|
|
21
|
+
|
|
22
|
+
## 0.5.10
|
|
23
|
+
|
|
24
|
+
- Show one Windows performance-GPU flag advisory for the current Chromium
|
|
25
|
+
browser, including Edge, Brave, Opera, and Vivaldi. Browsers that conceal
|
|
26
|
+
their identity use their own flags page through the generic `about://` address.
|
|
27
|
+
- Make the notice conditional on having multiple GPUs, cover every observed
|
|
28
|
+
GPU vendor, and omit the notice on Firefox, Safari, mobile, and non-Windows
|
|
29
|
+
platforms. No additional GPU flags or automatic settings changes are included.
|
|
30
|
+
|
|
3
31
|
## 0.5.9
|
|
4
32
|
|
|
5
33
|
- Renamed the built-in TWiN Cloud provider and default-model preference sentinel
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ version-locked SDK runtime, while an integrated Arcane checkout uses its live
|
|
|
19
19
|
`arcane/` runtime. Both profiles preserve the same app URLs, theme, packaging,
|
|
20
20
|
event, cancellation, and browser run contracts.
|
|
21
21
|
|
|
22
|
-
This checkout defines the `0.5.
|
|
22
|
+
This checkout defines the `0.5.11` SDK contract. Applications pin one exact npm
|
|
23
23
|
version and lockfile; registry state is deliberately not baked into application
|
|
24
24
|
artifacts.
|
|
25
25
|
|
|
@@ -29,16 +29,99 @@ The app repository's exact dependency and lockfile select the SDK; changing that
|
|
|
29
29
|
selection is an explicit repository update. Tests and checks run only when the
|
|
30
30
|
user expressly selects them, or when required for a selected release output.
|
|
31
31
|
|
|
32
|
+
## Beginner quick start
|
|
33
|
+
|
|
34
|
+
Create one browser application, install its pinned SDK, and start its source
|
|
35
|
+
server:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx arcane-os@0.5.11 new hello-speech --path ./hello-speech --target browser
|
|
39
|
+
cd hello-speech
|
|
40
|
+
npm install
|
|
41
|
+
npm run dev
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Open the URL printed by the server. The generated page owns its import map and
|
|
45
|
+
Arcane theme; its application module is `apps/hello-speech/modules/App.js`.
|
|
46
|
+
`arcane/AI` is a managed **browser import**, not an npm-exported Node inference
|
|
47
|
+
module.
|
|
48
|
+
|
|
49
|
+
For a first spoken sentence, copy the application-owned
|
|
50
|
+
[`speech-selection.js` configuration from the speech quick start](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/reference/ai/browser-speech.md#quick-start-say-one-sentence)
|
|
51
|
+
beside `App.js`, then use this module. That one configuration file defines the
|
|
52
|
+
upstream runtime, model, dtype, and voice. This module creates the application's
|
|
53
|
+
DBOPFS store; the SDK creates and manages its speech providers and Workers.
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
import arcaneThemeReady from 'arcane/ThemeBootstrap';
|
|
57
|
+
import AI, { AI_BROWSER_SPEECH_CONFIGURATION_PROTOCOL } from 'arcane/AI';
|
|
58
|
+
import DBOPFS from 'arcane/DBOPFS';
|
|
59
|
+
import { speechSelection } from './speech-selection.js';
|
|
60
|
+
|
|
61
|
+
await arcaneThemeReady;
|
|
62
|
+
const dbopfs = new DBOPFS();
|
|
63
|
+
await dbopfs.readyPromise;
|
|
64
|
+
const ai = new AI();
|
|
65
|
+
await ai.configureBrowserSpeech({
|
|
66
|
+
protocol: AI_BROWSER_SPEECH_CONFIGURATION_PROTOCOL,
|
|
67
|
+
id: 'hello-speech',
|
|
68
|
+
dbopfs,
|
|
69
|
+
tts: {
|
|
70
|
+
providerId: 'hello-kokoro',
|
|
71
|
+
model: speechSelection.model,
|
|
72
|
+
runtime: speechSelection.runtime,
|
|
73
|
+
offline: false
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const button = document.createElement('button');
|
|
78
|
+
button.textContent = 'Load voice and say hello';
|
|
79
|
+
document.body.append(button);
|
|
80
|
+
button.addEventListener('click', async function sayHello() {
|
|
81
|
+
button.disabled = true;
|
|
82
|
+
try {
|
|
83
|
+
await ai.setSpeechMuted(false);
|
|
84
|
+
console.log(ai.providerRuntime.status('tts', { execution: true }).execution);
|
|
85
|
+
const prepared = await ai.streamTTS('Hello from Arcane. ', true);
|
|
86
|
+
console.log('Speech preparation completed:', prepared);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error(error.code, error.message);
|
|
89
|
+
} finally {
|
|
90
|
+
button.disabled = false;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The button explicitly loads/unmutes the selected model and requests speech.
|
|
96
|
+
The first load can download the app-selected runtime/model/voice; the browser
|
|
97
|
+
may need another audio-unlock gesture after a long load. Keep the complete
|
|
98
|
+
visual response available alongside speech.
|
|
99
|
+
|
|
100
|
+
Capacity 4 means up to four segments synthesize at once. Segment 5 and later
|
|
101
|
+
wait in the SDK's FIFO queue; they are not dropped. Synthesis may finish out of
|
|
102
|
+
order, but playback waits for earlier segments and plays exact input order.
|
|
103
|
+
Each slot owns a Worker/model session, so raising capacity trades memory for
|
|
104
|
+
latency.
|
|
105
|
+
|
|
106
|
+
Continue with [streaming chunks, device selection, cancellation, status, and cleanup](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/reference/ai/browser-speech.md),
|
|
107
|
+
the [tiny TWiN Cloud request and saved-preference migration](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/reference/ai/twin-cloud.md),
|
|
108
|
+
or the [maintained WASM voice-chat example](https://github.com/TheWizardNexus/arcane-os-sdk/tree/main/examples/wasm-ai-demo).
|
|
109
|
+
The installed package also includes `docs/` and the maintained example source:
|
|
110
|
+
open `node_modules/arcane-os/docs/reference/ai/browser-speech.md`,
|
|
111
|
+
`node_modules/arcane-os/docs/reference/ai/twin-cloud.md`, or
|
|
112
|
+
`node_modules/arcane-os/examples/wasm-ai-demo/README.md` locally. Public links
|
|
113
|
+
above work from both npm and GitHub.
|
|
114
|
+
|
|
32
115
|
## Developer API reference
|
|
33
116
|
|
|
34
|
-
Start with the [capability-first developer reference](docs/reference/README.md).
|
|
117
|
+
Start with the [capability-first developer reference](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/reference/README.md).
|
|
35
118
|
It follows Arcane's MDN-style model and covers every public package export, CLI
|
|
36
119
|
command, synchronized runtime module, entity, component, Arcane Core member,
|
|
37
|
-
and Arcane Ollama method. Use the [availability and normalization matrix](docs/reference/availability-and-normalization.md)
|
|
120
|
+
and Arcane Ollama method. Use the [availability and normalization matrix](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/reference/availability-and-normalization.md)
|
|
38
121
|
to distinguish Node, browser, native, cloud, and cross-host behavior; protocol
|
|
39
|
-
mechanics are kept in the folded/deep-linked [protocol guide](docs/reference/protocols.md).
|
|
40
|
-
The [behavioral-testing guide](docs/reference/behavioral-testing.md) explains the
|
|
41
|
-
executable contract, while the [machine-readable inventories](docs/reference/inventory/)
|
|
122
|
+
mechanics are kept in the folded/deep-linked [protocol guide](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/reference/protocols.md).
|
|
123
|
+
The [behavioral-testing guide](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/reference/behavioral-testing.md) explains the
|
|
124
|
+
executable contract, while the [machine-readable inventories](https://github.com/TheWizardNexus/arcane-os-sdk/tree/main/docs/reference/inventory/)
|
|
42
125
|
make completeness independently checkable.
|
|
43
126
|
|
|
44
127
|
## Central event instrumentation
|
|
@@ -54,7 +137,7 @@ off-by-default diagnostic option.
|
|
|
54
137
|
|
|
55
138
|
Recording is off by default. Once explicitly enabled, a session retains its
|
|
56
139
|
complete recorded content until the caller clears it or disables recording.
|
|
57
|
-
Review [the EventManager guide](docs/event-manager.md)
|
|
140
|
+
Review [the EventManager guide](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/event-manager.md)
|
|
58
141
|
before enabling DOM values, node content, event details, source stacks, or live
|
|
59
142
|
event redispatch. Password targets, text-entry details, clipboard data, URL
|
|
60
143
|
attributes, and common credential keys are excluded or redacted by default.
|
|
@@ -90,10 +173,18 @@ Kokoro (`LOCAL_SPEACH` / `kokoro`) owns speech synthesis. Neither audio route
|
|
|
90
173
|
uses the TWiN key, and neither requires a cloud audio key.
|
|
91
174
|
|
|
92
175
|
The built-in provider and default-model preference sentinel are both `TWIN`.
|
|
93
|
-
Applications upgrading saved
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
176
|
+
Applications upgrading saved preference tuples must replace only uppercase
|
|
177
|
+
`OPENAI` in slot 0 (LLM provider) and slot 3 (default-model sentinel) with
|
|
178
|
+
`TWIN` through the existing application preference owner before importing
|
|
179
|
+
`AI.js` or any module that imports it, and before AI preference hydration.
|
|
180
|
+
Use dynamic import after migration; module evaluation can instantiate AI
|
|
181
|
+
immediately when the user is already ready. Keep every other
|
|
182
|
+
value unchanged, including `openai-gpt-oss-120b` and `openai-gpt-oss-20b`.
|
|
183
|
+
The SDK provides no built-in `OPENAI` alias and does not rewrite saved
|
|
184
|
+
preferences. OpenAI-compatible wire terminology and the separate Core
|
|
185
|
+
`provider:'openai'` contract are unchanged. The
|
|
186
|
+
[TWiN quick start and migration recipe](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/reference/ai/twin-cloud.md)
|
|
187
|
+
show the exact application-owned operation.
|
|
97
188
|
|
|
98
189
|
`fetchRequest()` and `streamRequest()` accept the provider-neutral
|
|
99
190
|
`reasoningEffort` option with `none`, `low`, `medium`, `high`, or `max`. TWiN
|
|
@@ -110,6 +201,8 @@ profile. Each descriptor uses one ordered `files` array, so monolithic and
|
|
|
110
201
|
split GGUF models share the same contract:
|
|
111
202
|
|
|
112
203
|
```js
|
|
204
|
+
import { createBrowserModelSource } from 'arcane-os/ai/browser-wasm';
|
|
205
|
+
|
|
113
206
|
const source=createBrowserModelSource({
|
|
114
207
|
id:'app-model',
|
|
115
208
|
files:[
|
|
@@ -157,7 +250,7 @@ provider factories. The package contains the plain-JavaScript provider and
|
|
|
157
250
|
Worker machinery, not speech runtimes, models, voices, or a CDN default. An app
|
|
158
251
|
must supply each runtime/model selection explicitly. Speech roles
|
|
159
252
|
load, cancel, unload, fail, and recover independently, so speech failure never
|
|
160
|
-
silently falls back or prevents text chat. Kokoro defaults to a
|
|
253
|
+
silently falls back or prevents text chat. Kokoro defaults to a four-slot Worker
|
|
161
254
|
and model-session pool: it selects WebGPU when the browser can load the complete
|
|
162
255
|
pool and otherwise recreates that pool on WASM. Apps may select `webgpu` or
|
|
163
256
|
`wasm` explicitly and may set the bounded TTS capacity from one through four.
|
|
@@ -204,10 +297,9 @@ uses the same controller for automatic memory extraction.
|
|
|
204
297
|
Create a new repository-shaped Arcane application with the exact stable SDK:
|
|
205
298
|
|
|
206
299
|
```bash
|
|
207
|
-
npx arcane-os@0.5.
|
|
300
|
+
npx arcane-os@0.5.11 new my-app --path ./my-app --target portable --git
|
|
208
301
|
cd my-app
|
|
209
302
|
npm install
|
|
210
|
-
npm run check
|
|
211
303
|
npm run dev
|
|
212
304
|
```
|
|
213
305
|
|
|
@@ -215,7 +307,7 @@ To enroll an existing repository, install the exact SDK and initialize only
|
|
|
215
307
|
missing Arcane files:
|
|
216
308
|
|
|
217
309
|
```bash
|
|
218
|
-
npm install --save-dev --save-exact arcane-os@0.5.
|
|
310
|
+
npm install --save-dev --save-exact arcane-os@0.5.11
|
|
219
311
|
npm exec -- arcane init my-app --target portable
|
|
220
312
|
```
|
|
221
313
|
|
|
@@ -231,7 +323,7 @@ npm exec -- arcane-os targets
|
|
|
231
323
|
No global SDK install or standalone Arcane CLI is required. The application
|
|
232
324
|
repository's exact npm dependency and lockfile own the CLI and toolchain version.
|
|
233
325
|
|
|
234
|
-
Use `npx arcane-os@0.5.
|
|
326
|
+
Use `npx arcane-os@0.5.11` for the initial bootstrap because it names this npm
|
|
235
327
|
package explicitly; bare `npx arcane` outside an installed project could resolve
|
|
236
328
|
a different package. Both installed commands invoke the same headless toolchain.
|
|
237
329
|
Project-local npm scripts use the SDK pinned by that app's `package-lock.json`,
|
|
@@ -246,14 +338,12 @@ tarball install in the app's package manifest and lock:
|
|
|
246
338
|
```bash
|
|
247
339
|
# From the arcane-os-sdk checkout
|
|
248
340
|
npm ci
|
|
249
|
-
npm run check
|
|
250
341
|
npm run pack:local
|
|
251
342
|
node ./bin/arcane.mjs new local-app --path ../local-app --target portable --git
|
|
252
343
|
|
|
253
344
|
# From the generated app repository
|
|
254
345
|
cd ../local-app
|
|
255
|
-
npm install --save-dev --save-exact ../arcane-os-sdk/arcane-os-0.5.
|
|
256
|
-
npm run check
|
|
346
|
+
npm install --save-dev --save-exact ../arcane-os-sdk/arcane-os-0.5.11.tgz
|
|
257
347
|
npm ci
|
|
258
348
|
```
|
|
259
349
|
|
|
@@ -262,7 +352,7 @@ same location. The lockfile retains the selected package dependency while
|
|
|
262
352
|
Arcane uses the installed package name and version. Local directory `file:` dependencies are not
|
|
263
353
|
accepted because npm may install them as links; use a packed `.tgz`. A GitHub
|
|
264
354
|
runner also needs that tarball at the locked path. After publication, replace
|
|
265
|
-
the local declaration with the exact `arcane-os@0.5.
|
|
355
|
+
the local declaration with the exact `arcane-os@0.5.11` registry package and
|
|
266
356
|
commit the regenerated lock.
|
|
267
357
|
|
|
268
358
|
Generated repositories use `npm ci --ignore-scripts` in CI. Run dependency
|
|
@@ -393,14 +483,15 @@ npm run test:integration
|
|
|
393
483
|
npm run test:regression
|
|
394
484
|
```
|
|
395
485
|
|
|
396
|
-
|
|
486
|
+
Run a named set or `npm test` only when explicitly selecting that verification,
|
|
487
|
+
or when required for a selected release output. Large
|
|
397
488
|
fixtures stay inside one isolated file process and expose smaller nested cases,
|
|
398
489
|
so the report shows the individual behaviors without repeating setup, builds,
|
|
399
490
|
package installation, or assertions.
|
|
400
491
|
|
|
401
492
|
## Current target support
|
|
402
493
|
|
|
403
|
-
Version `0.5.
|
|
494
|
+
Version `0.5.11` exposes one browser target and five explicitly paired
|
|
404
495
|
native development targets: a non-runnable portable directory, a
|
|
405
496
|
Windows x64 unsigned-local-test EXE bundle, Linux x64 and Linux ARM64
|
|
406
497
|
unsigned-local-test DEBs, and an Android development-signed APK. The
|
|
@@ -502,11 +593,11 @@ artifact. Portable output is never represented as an executable, and unsigned
|
|
|
502
593
|
or development-signed evidence is never represented as production signing or
|
|
503
594
|
release acceptance.
|
|
504
595
|
|
|
505
|
-
See [docs/platform-targets.md](docs/platform-targets.md) for the matrix and
|
|
506
|
-
[docs/architecture.md](docs/architecture.md) for the boundary. The exact
|
|
596
|
+
See [docs/platform-targets.md](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/platform-targets.md) for the matrix and
|
|
597
|
+
[docs/architecture.md](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/architecture.md) for the boundary. The exact
|
|
507
598
|
minimum-version and required-contract compatibility rule is documented in
|
|
508
|
-
[docs/compatibility.md](docs/compatibility.md). The issue-ready
|
|
509
|
-
extraction sequence is tracked in [docs/roadmap.md](docs/roadmap.md).
|
|
599
|
+
[docs/compatibility.md](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/compatibility.md). The issue-ready
|
|
600
|
+
extraction sequence is tracked in [docs/roadmap.md](https://github.com/TheWizardNexus/arcane-os-sdk/blob/main/docs/roadmap.md).
|
|
510
601
|
|
|
511
602
|
## Canonical app descriptor
|
|
512
603
|
|
|
@@ -21,7 +21,7 @@ const TTS_SAMPLE_RATE = 24_000;
|
|
|
21
21
|
const TTS_RESPONSE_FORMAT = "wav";
|
|
22
22
|
const TTS_EXECUTION_DEVICES = new Set(["auto", "webgpu", "wasm"]);
|
|
23
23
|
const DEFAULT_TTS_EXECUTION_DEVICE = "auto";
|
|
24
|
-
const DEFAULT_TTS_MAX_CONCURRENT_REQUESTS =
|
|
24
|
+
const DEFAULT_TTS_MAX_CONCURRENT_REQUESTS = 4;
|
|
25
25
|
const MAX_TTS_CONCURRENT_REQUESTS = 4;
|
|
26
26
|
const ROLE_REQUEST_REASON = completeValue({
|
|
27
27
|
stt: "stt-transcription-cancelled",
|
|
@@ -20,15 +20,12 @@ const AI_PROVIDER_PROTOCOL = "arcane-ai-provider/2";
|
|
|
20
20
|
const AI_MODEL_AUTHORITY_PROTOCOL = "arcane-ai-model-authority/1";
|
|
21
21
|
const WEBGPU_ADAPTER_SELECTED_EVENT = "arcane.ai.browser-wasm.webgpu.adapter.selected";
|
|
22
22
|
const WEBGPU_ADAPTER_SELECTION_PROTOCOL = "arcane-ai-webgpu-adapter-selection/1";
|
|
23
|
-
const CHROME_HIGH_PERFORMANCE_GPU_FLAG_URL =
|
|
24
|
-
"chrome://flags/#force-high-performance-gpu";
|
|
25
23
|
const MODEL_LOAD_HEARTBEAT_MS = 5_000;
|
|
26
24
|
const DEFAULT_MODEL_DOWNLOAD_CONCURRENCY = 4;
|
|
27
25
|
const MODEL_DOWNLOAD_PROGRESS_INTERVAL_MS = 250;
|
|
28
26
|
const MODEL_DOWNLOAD_SPEED_WINDOW_MS = 5_000;
|
|
29
27
|
const MODEL_DOWNLOAD_MAX_RANGE_PARTS = 4_096;
|
|
30
28
|
const MODEL_DOWNLOAD_TARGET_RANGE_BYTES = 4_000_000;
|
|
31
|
-
const INTEL_VENDOR_ID = 0x8086;
|
|
32
29
|
const CAPABILITY_POLICY_PROTOCOL = "arcane-ai-browser-capability-policy/1";
|
|
33
30
|
let highPerformanceGpuNoticeShown = false;
|
|
34
31
|
|
|
@@ -263,44 +260,71 @@ function publicDescriptor(source) {
|
|
|
263
260
|
return modelDescriptor(source);
|
|
264
261
|
}
|
|
265
262
|
|
|
266
|
-
function
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
263
|
+
function highPerformanceGpuBrowser() {
|
|
264
|
+
const navigatorObject = globalThis.navigator;
|
|
265
|
+
const userAgent = String(navigatorObject?.userAgent ?? "");
|
|
266
|
+
const clientHints = navigatorObject?.userAgentData;
|
|
267
|
+
const platform = String(clientHints?.platform || navigatorObject?.platform || userAgent);
|
|
268
|
+
if (
|
|
269
|
+
!/\b(?:Windows|Win32|Win64)\b/iu.test(platform)
|
|
270
|
+
|| clientHints?.mobile === true
|
|
271
|
+
|| /\b(?:Android|iPhone|iPad|iPod|Mobile)\b/iu.test(userAgent)
|
|
272
|
+
) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
271
275
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
276
|
+
const brands = new Set();
|
|
277
|
+
for (const entry of clientHints?.brands ?? []) {
|
|
278
|
+
brands.add(entry.brand);
|
|
279
|
+
}
|
|
280
|
+
// Vivaldi can append its identity while also identifying as Edge or Chrome.
|
|
281
|
+
if (brands.has("Vivaldi") || /\bVivaldi\//u.test(userAgent)) {
|
|
282
|
+
return { name: "Vivaldi", url: "vivaldi://flags/#force-high-performance-gpu" };
|
|
283
|
+
}
|
|
284
|
+
if (brands.has("Brave") || typeof navigatorObject?.brave?.isBrave === "function") {
|
|
285
|
+
return { name: "Brave", url: "brave://flags/#force-high-performance-gpu" };
|
|
286
|
+
}
|
|
287
|
+
if (brands.has("Opera") || /\bOPR\//u.test(userAgent)) {
|
|
288
|
+
return { name: "Opera", url: "opera://flags/#force-high-performance-gpu" };
|
|
289
|
+
}
|
|
290
|
+
if (brands.has("Microsoft Edge") || /\bEdg\//u.test(userAgent)) {
|
|
291
|
+
return { name: "Microsoft Edge", url: "edge://flags/#force-high-performance-gpu" };
|
|
292
|
+
}
|
|
293
|
+
if (
|
|
294
|
+
brands.has("Chromium")
|
|
295
|
+
|| brands.has("Google Chrome")
|
|
296
|
+
|| /\b(?:Chrome|Chromium)\//u.test(userAgent)
|
|
297
|
+
) {
|
|
298
|
+
// Some Chromium browsers mask their brand. about:// uses their own flags page.
|
|
299
|
+
return { name: "your browser", url: "about://flags/#force-high-performance-gpu" };
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
281
302
|
}
|
|
282
303
|
|
|
283
|
-
function
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
+
function notifyHighPerformanceGpu(adapter) {
|
|
305
|
+
if (highPerformanceGpuNoticeShown) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const browser = highPerformanceGpuBrowser();
|
|
309
|
+
if (!browser) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
highPerformanceGpuNoticeShown = true;
|
|
313
|
+
try {
|
|
314
|
+
globalThis.open?.(browser.url, "_blank", "noopener,noreferrer");
|
|
315
|
+
} catch {
|
|
316
|
+
// Browsers may reject internal-page navigation from web content.
|
|
317
|
+
}
|
|
318
|
+
const adapterName = adapter.description || adapter.name
|
|
319
|
+
|| [adapter.vendor, adapter.architecture].filter(Boolean).join(" ")
|
|
320
|
+
|| "the available WebGPU adapter";
|
|
321
|
+
globalThis.alert?.(
|
|
322
|
+
`Selected WebGPU adapter: ${adapterName}.\n\n`
|
|
323
|
+
+ `If this computer has multiple GPUs, enable “Force High Performance GPU” in ${browser.name} `
|
|
324
|
+
+ "to request the high-performance GPU when available. "
|
|
325
|
+
+ `Then completely close and reopen ${browser.name} before loading the model again.\n\n`
|
|
326
|
+
+ `If the flags page did not open, paste ${browser.url} into the address bar.`,
|
|
327
|
+
);
|
|
304
328
|
}
|
|
305
329
|
|
|
306
330
|
function emitWebgpuAdapterSelection(source, runtime) {
|
|
@@ -322,7 +346,7 @@ function emitWebgpuAdapterSelection(source, runtime) {
|
|
|
322
346
|
category: "capability",
|
|
323
347
|
}));
|
|
324
348
|
} finally {
|
|
325
|
-
|
|
349
|
+
notifyHighPerformanceGpu(webgpu.adapter);
|
|
326
350
|
}
|
|
327
351
|
}
|
|
328
352
|
|