arcane-os 0.2.0 → 0.2.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 +35 -0
- package/README.md +8 -8
- package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +5 -5
- package/browser-runtime/ai/browser-speech-providers.mjs +331 -25
- package/docs/architecture.md +2 -2
- package/docs/reference/README.md +79 -13
- package/docs/reference/ai/browser-speech.md +336 -0
- package/docs/reference/ai/browser-wasm.md +207 -82
- package/docs/reference/availability-and-normalization.md +30 -4
- package/docs/reference/behavioral-testing.md +4 -1
- package/docs/reference/cli.md +29 -10
- package/docs/reference/core/arcane-ai-contracts.md +43 -9
- package/docs/reference/inventory/package-api.json +110 -14
- package/docs/reference/inventory/runtime-components.json +19 -6
- package/docs/reference/inventory/runtime-modules.json +113 -9
- package/docs/reference/protocols.md +260 -38
- package/docs/reference/runtime-components.md +108 -15
- package/docs/reference/runtime-modules.md +422 -8
- package/docs/reference/sdk-api.md +626 -85
- package/package.json +1 -1
- package/runtime/ARCANE_RUNTIME_RELEASE.json +19 -19
- package/runtime/arcane/components/chat.html +288 -52
- package/runtime/arcane/components/speech.html +339 -15
- package/runtime/arcane/modules/AI.js +1245 -136
- package/runtime/arcane/modules/AIProviderRuntime.js +299 -30
- package/runtime/arcane/modules/AIRuntimeState.js +23 -4
- package/runtime/arcane/modules/ConfiguredAIChatSession.js +93 -8
- package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +448 -24
- package/runtime/arcane/modules/LocalAIReadinessController.js +1 -1
- package/schemas/arcane-lock.schema.json +6 -4
- package/src/dev-server.mjs +29 -13
- package/src/doctor.mjs +1 -3
- package/src/import-map.mjs +134 -83
- package/src/packager/core.mjs +311 -39
- package/src/scaffold.mjs +45 -17
- package/src/templates/workspace-template.mjs +23 -4
- package/src/toolchain.mjs +10 -2
- package/src/workspace.mjs +177 -24
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
The npm package exposes a Node.js ESM control plane, the Node-and-browser
|
|
4
4
|
`arcane-os/event-manager` entrypoint, and the browser-only
|
|
5
|
-
`arcane-os/ai/browser-wasm`
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
`arcane-os/ai/browser-wasm` and `arcane-os/ai/browser-speech` entrypoints.
|
|
6
|
+
Those package subpaths are distinct from application-facing projection modules
|
|
7
|
+
in the managed browser map, such as `arcane/AIProviderRuntime`,
|
|
8
|
+
`arcane/AIRuntimeState`, and `arcane/ThemeBootstrap`. Applications use those
|
|
9
|
+
mapped runtime modules and call `globalThis.Arcane` for capability-gated host
|
|
10
|
+
behavior; they are not additional `package.json#exports` entrypoints.
|
|
8
11
|
|
|
9
12
|
This page is the canonical inventory for every JavaScript name reachable through `package.json#exports`. The same binding can appear at the root and a focused subpath; those entrypoints are listed together. The root workspace `discoverApps` and the low-level packager `discoverApps` are intentionally separate records because they are different functions.
|
|
10
13
|
|
|
@@ -14,7 +17,7 @@ This table is the Node `package.json#exports` map: it defines package
|
|
|
14
17
|
entrypoints for SDK/tooling code. It is distinct from the generated browser
|
|
15
18
|
import map that resolves application-facing `arcane/*` modules and the focused
|
|
16
19
|
EventManager entry. See [browser runtime delivery](protocols.md#browser-runtime-delivery)
|
|
17
|
-
for that
|
|
20
|
+
for that 91-entry physical-runtime contract in SDK `0.2.1`.
|
|
18
21
|
|
|
19
22
|
| Specifier | Purpose |
|
|
20
23
|
| --- | --- |
|
|
@@ -30,6 +33,7 @@ for that 86-entry physical-runtime contract.
|
|
|
30
33
|
| `arcane-os/release-bundle` | Deterministic external release bundles. |
|
|
31
34
|
| `arcane-os/event-manager` | Central synchronous events, bounded time-travel history, playback, and optional DOM instrumentation. |
|
|
32
35
|
| `arcane-os/ai/browser-wasm` | Caller-selected browser-local Wllama inference, configurable DBOPFS model checks, streaming, cancellation, and structural tool-call results. |
|
|
36
|
+
| `arcane-os/ai/browser-speech` | Caller-selected browser-local Whisper STT and Kokoro TTS provider mechanisms, authenticated DBOPFS artifacts, Workers, and cancellation; no model or adapter bytes. |
|
|
33
37
|
|
|
34
38
|
JSON schemas, the runtime manifest, and `package.json` are data-only export subpaths. In Node ESM, import JSON with `with {type: 'json'}`, or resolve and read it explicitly.
|
|
35
39
|
|
|
@@ -43,6 +47,12 @@ Protocol mechanics are intentionally kept in the [deep protocol guide](protocols
|
|
|
43
47
|
|
|
44
48
|
## Canonical member inventory
|
|
45
49
|
|
|
50
|
+
SDK `0.2.1` exports exactly 169 distinct JavaScript members across 13
|
|
51
|
+
JavaScript entrypoints. The complete export map has 23 subpaths: the other 10
|
|
52
|
+
are the runtime manifest, eight JSON Schemas, and package metadata. Runtime
|
|
53
|
+
projection modules in the managed browser map are cataloged separately in
|
|
54
|
+
[Runtime modules](runtime-modules.md).
|
|
55
|
+
|
|
46
56
|
| Member | Kind | Import | Group | Availability |
|
|
47
57
|
| --- | --- | --- | --- | --- |
|
|
48
58
|
| `APP_BUNDLE_DESCRIPTOR_NAME` | constant | `arcane-os` | Packaging and release bundles | Node |
|
|
@@ -66,6 +76,7 @@ Protocol mechanics are intentionally kept in the [deep protocol guide](protocols
|
|
|
66
76
|
| `ARCANE_UPSTREAM_COMMIT` | constant | `arcane-os` | Identity and protocol constants | Node |
|
|
67
77
|
| `ARCANE_UPSTREAM_REPOSITORY` | constant | `arcane-os` | Identity and protocol constants | Node |
|
|
68
78
|
| `ArcaneError` | class | `arcane-os` | Errors | Node |
|
|
79
|
+
| `adaptV1LlmProvider()` | function | `arcane-os/ai/browser-wasm` | Browser-WASM local AI | Browser; the wrapped provider retains its own WebGPU, storage, model, and lifecycle requirements |
|
|
69
80
|
| `assertIntegratedNativeToolchain()` | function | `arcane-os` | Targets, native plans, and providers | Node; selected browser/native target or provider as documented |
|
|
70
81
|
| `assertIntegratedPortableToolchain()` | function | `arcane-os` | Targets, native plans, and providers | Node; selected browser/native target or provider as documented |
|
|
71
82
|
| `assertNativeApplicationToolchainCompatibility()` | function | `arcane-os` | Targets, native plans, and providers | Node; selected browser/native target or provider as documented |
|
|
@@ -79,6 +90,7 @@ Protocol mechanics are intentionally kept in the [deep protocol guide](protocols
|
|
|
79
90
|
| `authenticateSharedPayloadSnapshot()` | function | `arcane-os` | Packaging and release bundles | Node |
|
|
80
91
|
| `buildApplication()` | function | `arcane-os` | Headless toolchain operations | Node; selected operation may produce browser or native output |
|
|
81
92
|
| `buildTarget()` | function | `arcane-os` | Targets, native plans, and providers | Node; selected browser/native target or provider as documented |
|
|
93
|
+
| `BROWSER_SPEECH_ARTIFACT_PROTOCOL` | constant | `arcane-os/ai/browser-speech` | Browser speech providers | Browser metadata; model/runtime use requires DBOPFS, Web Locks, Workers, and caller-supplied immutable artifacts |
|
|
82
94
|
| `BROWSER_WASM_RUNTIME_AUTHORITY` | constant | `arcane-os/ai/browser-wasm` | Browser-WASM local AI | Browser metadata; no model or DBOPFS required to inspect |
|
|
83
95
|
| `bumpVersion()` | function | `arcane-os/packager` | Packaging and release bundles | Node |
|
|
84
96
|
| `bundleApplication()` | function | `arcane-os` | Headless toolchain operations | Node; selected operation may produce browser or native output |
|
|
@@ -88,10 +100,14 @@ Protocol mechanics are intentionally kept in the [deep protocol guide](protocols
|
|
|
88
100
|
| `createApplication()` | function | `arcane-os` | Headless toolchain operations | Node; selected operation may produce browser or native output |
|
|
89
101
|
| `createArcaneAI()` | function | `arcane-os/ai/browser-wasm` | Browser-WASM local AI | Browser; compatible LLM provider or controller required |
|
|
90
102
|
| `createAppReleaseBundle()` | function | `arcane-os` | Packaging and release bundles | Node |
|
|
103
|
+
| `createBrowserKokoroProvider()` | function | `arcane-os/ai/browser-speech` | Browser speech providers | Browser with DBOPFS, Web Locks, Workers, object URLs, and caller-admitted Kokoro runtime/model artifacts |
|
|
91
104
|
| `createBrowserModelSource()` | function | `arcane-os/ai/browser-wasm` | Browser-WASM local AI | Browser Fetch with a readable response body |
|
|
92
|
-
| `
|
|
105
|
+
| `createBrowserSpeechAuthority()` | function | `arcane-os/ai/browser-speech` | Browser speech providers | Browser descriptor construction; use requires the selected storage and provider Web APIs |
|
|
106
|
+
| `createBrowserWasmLlmProvider()` | function | `arcane-os/ai/browser-wasm` | Browser-WASM local AI | Browser secure context with WebAssembly, OPFS/DBOPFS, WebGPU, and admitted full-offload evidence; no CPU fallback |
|
|
107
|
+
| `createBrowserWhisperProvider()` | function | `arcane-os/ai/browser-speech` | Browser speech providers | Browser with DBOPFS, Web Locks, Workers, object URLs, and caller-admitted Whisper runtime/model artifacts |
|
|
93
108
|
| `createCanonicalUstarHeader()` | function | `arcane-os` | Packaging and release bundles | Node |
|
|
94
109
|
| `createDbopfsModelStore()` | function | `arcane-os/ai/browser-wasm` | Browser-WASM local AI | Browser with a ready DBOPFS instance and OPFS |
|
|
110
|
+
| `createDbopfsSpeechArtifactStore()` | function | `arcane-os/ai/browser-speech` | Browser speech providers | Browser with ready DBOPFS, Web Locks, Fetch, File/Blob, and object URLs |
|
|
95
111
|
| `createNativeBuildPlan()` | function | `arcane-os` | Targets, native plans, and providers | Node; selected browser/native target or provider as documented |
|
|
96
112
|
| `createNativeTargetAdapter()` | function | `arcane-os` | Targets, native plans, and providers | Node; selected browser/native target or provider as documented |
|
|
97
113
|
| `createReporter()` | function | `arcane-os` | Events, processes, and testing | Node |
|
|
@@ -787,7 +803,30 @@ Builds and authenticates one browser application release through the low-level p
|
|
|
787
803
|
async packageApp(options)
|
|
788
804
|
```
|
|
789
805
|
|
|
790
|
-
Import it from `arcane-os` or `arcane-os/packager`.
|
|
806
|
+
Import it from `arcane-os` or `arcane-os/packager`. For a non-dry-run external
|
|
807
|
+
package, the result includes `importMapReceipt`. That frozen receipt binds the
|
|
808
|
+
artifact, configured entry, every additional included `.html`/`.htm` document,
|
|
809
|
+
and their exact committed bytes/hashes. Each admitted document receives the
|
|
810
|
+
same deterministic map. The package root also contains the public
|
|
811
|
+
`ARCANE_RUNTIME_PROJECTION.json` inventory:
|
|
812
|
+
|
|
813
|
+
```javascript
|
|
814
|
+
{
|
|
815
|
+
schemaVersion: 1,
|
|
816
|
+
kind: 'arcane-app-runtime-projection',
|
|
817
|
+
sdkVersion: '0.2.1',
|
|
818
|
+
pathPrefix: 'arcane/',
|
|
819
|
+
fileCount,
|
|
820
|
+
totalBytes,
|
|
821
|
+
contentSha256,
|
|
822
|
+
files: [{path, bytes, sha256}]
|
|
823
|
+
}
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
That projection is authenticated by the private application release inventory
|
|
827
|
+
and the admitted runtime authorities. It is not a replacement for either
|
|
828
|
+
receipt. Incomplete, changed, forged, or internally inconsistent projection
|
|
829
|
+
data rejects with `ARCANE_RUNTIME_PROJECTION_INVALID`.
|
|
791
830
|
|
|
792
831
|
### Availability and normalization
|
|
793
832
|
|
|
@@ -798,9 +837,13 @@ Import it from `arcane-os` or `arcane-os/packager`. The signature above states w
|
|
|
798
837
|
```javascript
|
|
799
838
|
import {packageApp} from 'arcane-os';
|
|
800
839
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
840
|
+
const packaged = await packageApp({
|
|
841
|
+
workspaceRoot: process.cwd(),
|
|
842
|
+
appId: 'hello-world'
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
console.log(packaged.importMapReceipt.documentPaths);
|
|
846
|
+
console.log(packaged.importMapReceipt.documentCount);
|
|
804
847
|
```
|
|
805
848
|
|
|
806
849
|
## PACKAGER_VERSION
|
|
@@ -2655,7 +2698,7 @@ The import-map operation also reports the stable operation-specific strings
|
|
|
2655
2698
|
`ARCANE_IMPORT_MAP_COLLISION`; package assembly can additionally report
|
|
2656
2699
|
`ARCANE_IMPORT_MAP_CLEANUP_FAILED`. They are normalized `ArcaneError.code`
|
|
2657
2700
|
values, but are not properties added to this frozen general registry in SDK
|
|
2658
|
-
`0.1
|
|
2701
|
+
`0.2.1`.
|
|
2659
2702
|
|
|
2660
2703
|
### Value and import
|
|
2661
2704
|
|
|
@@ -3300,10 +3343,42 @@ Runs canonical workspace, runtime, descriptor, and selected-app validation with
|
|
|
3300
3343
|
### Signature and result
|
|
3301
3344
|
|
|
3302
3345
|
```text
|
|
3303
|
-
async validateWorkspace({
|
|
3346
|
+
async validateWorkspace({
|
|
3347
|
+
workspaceRoot=process.cwd(),
|
|
3348
|
+
appId,
|
|
3349
|
+
allowMissingManagedImportMap=false,
|
|
3350
|
+
signal,
|
|
3351
|
+
onEvent
|
|
3352
|
+
}={})
|
|
3304
3353
|
```
|
|
3305
3354
|
|
|
3306
|
-
Import it from `arcane-os`.
|
|
3355
|
+
Import it from `arcane-os`. It resolves to a frozen validation receipt with
|
|
3356
|
+
`valid`, `workspaceMode`, `workspaceRoot`, `appId`, `appRoot`, the selected
|
|
3357
|
+
configuration/application, lock data, and completed checks. For an external
|
|
3358
|
+
workspace it additionally returns the exact installed package authority:
|
|
3359
|
+
|
|
3360
|
+
```javascript
|
|
3361
|
+
{
|
|
3362
|
+
sdkInstallation: {
|
|
3363
|
+
dependencyName,
|
|
3364
|
+
packageSource,
|
|
3365
|
+
canonicalPackageRoot,
|
|
3366
|
+
packageName: 'arcane-os',
|
|
3367
|
+
packageVersion: '0.2.1',
|
|
3368
|
+
runtimeRoot,
|
|
3369
|
+
browserRuntimeRoot,
|
|
3370
|
+
runtimeManifest,
|
|
3371
|
+
browserRuntimeManifest
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
```
|
|
3375
|
+
|
|
3376
|
+
The dependency can be named `arcane-os` or be one exact npm alias for
|
|
3377
|
+
`npm:arcane-os@0.2.1`. The selected installation must still be one direct,
|
|
3378
|
+
physical, non-link package directory whose manifest identifies exactly as
|
|
3379
|
+
`arcane-os@0.2.1`; duplicate canonical/alias declarations fail closed.
|
|
3380
|
+
`allowMissingManagedImportMap` is an internal packaging/development seam. An
|
|
3381
|
+
ordinary caller should leave it `false`.
|
|
3307
3382
|
|
|
3308
3383
|
### Availability and normalization
|
|
3309
3384
|
|
|
@@ -3314,9 +3389,13 @@ Import it from `arcane-os`. The signature above states whether settlement is syn
|
|
|
3314
3389
|
```javascript
|
|
3315
3390
|
import {validateWorkspace} from 'arcane-os';
|
|
3316
3391
|
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3392
|
+
const validation = await validateWorkspace({
|
|
3393
|
+
workspaceRoot: process.cwd(),
|
|
3394
|
+
appId: 'hello-world'
|
|
3395
|
+
});
|
|
3396
|
+
|
|
3397
|
+
console.log(validation.sdkInstallation?.dependencyName);
|
|
3398
|
+
console.log(validation.sdkInstallation?.packageVersion);
|
|
3320
3399
|
```
|
|
3321
3400
|
|
|
3322
3401
|
|
|
@@ -3472,9 +3551,10 @@ const toolchain = createToolchain({
|
|
|
3472
3551
|
}
|
|
3473
3552
|
});
|
|
3474
3553
|
|
|
3475
|
-
// Only this explicit call refreshes the managed map and HTML entry.
|
|
3554
|
+
// Only this explicit call refreshes the managed map and configured HTML entry.
|
|
3476
3555
|
const result = await toolchain.importMap();
|
|
3477
|
-
console.log(result.importMap.entryCount); //
|
|
3556
|
+
console.log(result.importMap.entryCount); // 91 in SDK 0.2.1
|
|
3557
|
+
console.log(result.importMap.documentPaths, result.importMap.documentCount);
|
|
3478
3558
|
```
|
|
3479
3559
|
|
|
3480
3560
|
## describeTargets()
|
|
@@ -3542,7 +3622,10 @@ Dispatches one named headless SDK operation with normalized acceptance, events,
|
|
|
3542
3622
|
The exact command `'import-map'` dispatches one app-scoped authenticated refresh
|
|
3543
3623
|
and returns `{workspaceRoot, workspaceMode, appId, importMap}`. A normal
|
|
3544
3624
|
`importMap` value binds the generated imports and the committed map/HTML file
|
|
3545
|
-
hashes
|
|
3625
|
+
hashes through `documentPaths`, `documentCount`, and the ordered `files`
|
|
3626
|
+
records. The direct operation supplies the configured entry only; packaging
|
|
3627
|
+
owns discovery of additional included browser documents. The canonical
|
|
3628
|
+
integrated-legacy layout returns its documented skip
|
|
3546
3629
|
record instead. This route mutates the two managed application files and has no
|
|
3547
3630
|
supported dry-run.
|
|
3548
3631
|
|
|
@@ -3574,13 +3657,20 @@ const result = await executeOperation('import-map', {
|
|
|
3574
3657
|
appId:'hello-world'
|
|
3575
3658
|
});
|
|
3576
3659
|
console.log(result.importMap.committed, result.importMap.entryCount);
|
|
3660
|
+
console.log(result.importMap.documentPaths, result.importMap.documentCount);
|
|
3577
3661
|
```
|
|
3578
3662
|
|
|
3579
3663
|
## packageApplication()
|
|
3580
3664
|
|
|
3581
3665
|
### Overview
|
|
3582
3666
|
|
|
3583
|
-
Runs the high-level package operation for one selected application.
|
|
3667
|
+
Runs the high-level package operation for one selected application. It
|
|
3668
|
+
authenticates the installed SDK/runtime authorities, injects one deterministic
|
|
3669
|
+
managed import map into every included `.html`/`.htm` browser document, and
|
|
3670
|
+
returns the low-level package result with its `importMapReceipt`. External
|
|
3671
|
+
packages publish `ARCANE_RUNTIME_PROJECTION.json`; private
|
|
3672
|
+
`ARCANE_APP_RELEASE.json` remains an internal verification authority rather
|
|
3673
|
+
than an application route.
|
|
3584
3674
|
|
|
3585
3675
|
### Signature and result
|
|
3586
3676
|
|
|
@@ -3599,9 +3689,12 @@ Import it from `arcane-os` or `arcane-os/toolchain`. The signature above states
|
|
|
3599
3689
|
```javascript
|
|
3600
3690
|
import {packageApplication} from 'arcane-os';
|
|
3601
3691
|
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3692
|
+
const result = await packageApplication({
|
|
3693
|
+
workspaceRoot: process.cwd(),
|
|
3694
|
+
appId: 'hello-world'
|
|
3695
|
+
});
|
|
3696
|
+
|
|
3697
|
+
console.log(result.release.importMapReceipt.documentCount);
|
|
3605
3698
|
```
|
|
3606
3699
|
|
|
3607
3700
|
## planApplication()
|
|
@@ -4944,7 +5037,8 @@ Deep-frozen authority for the browser-only runtime behind
|
|
|
4944
5037
|
`arcane-ai-browser-wasm/2`, `@wllama/wllama` `3.6.0`, the embedded llama.cpp
|
|
4945
5038
|
revision, the exact packaged JavaScript and WebAssembly assets, retained MIT
|
|
4946
5039
|
licenses, and the disabled compatibility-runtime/remote-model-helper policy.
|
|
4947
|
-
|
|
5040
|
+
Its execution policy requires WebGPU, proves full model offload, and declares
|
|
5041
|
+
`cpuFallback:false`. It contains no model weights or default model catalog.
|
|
4948
5042
|
|
|
4949
5043
|
### Value and import
|
|
4950
5044
|
|
|
@@ -4958,7 +5052,8 @@ inspecting it does not initialize Wllama, request storage, or download a model.
|
|
|
4958
5052
|
### Availability and normalization
|
|
4959
5053
|
|
|
4960
5054
|
**Browser metadata.** This is an immutable component receipt, not a provider,
|
|
4961
|
-
model, browser-permission grant, or proof that WebAssembly
|
|
5055
|
+
model, browser-permission grant, or proof that WebAssembly, OPFS, a secure
|
|
5056
|
+
context, or WebGPU is available.
|
|
4962
5057
|
|
|
4963
5058
|
### Example
|
|
4964
5059
|
|
|
@@ -4988,11 +5083,28 @@ createArcaneAI({ llm=null, provider=null, loadPolicy='on-demand', security }={})
|
|
|
4988
5083
|
```
|
|
4989
5084
|
|
|
4990
5085
|
At least one `llm` or `provider` is required. The frozen facade contains
|
|
4991
|
-
`llm`, `runtime`, `status`, `load`, `unload`, `probe`,
|
|
4992
|
-
`streamRequest`, and `dispose`. `status()` returns
|
|
4993
|
-
methods return the flat LLM status.
|
|
4994
|
-
`
|
|
4995
|
-
argument-string record. Use
|
|
5086
|
+
`llm`, `runtime`, `createChatSession`, `status`, `load`, `unload`, `probe`,
|
|
5087
|
+
`fetchRequest`, `streamRequest`, and `dispose`. `status()` returns
|
|
5088
|
+
`{llm: status}`; lifecycle methods return the flat LLM status.
|
|
5089
|
+
`fetchRequest()` returns the completion. `streamRequest()` consumes streaming
|
|
5090
|
+
and returns text or a tool-name-to-JSON-argument-string record. Use
|
|
5091
|
+
`ai.llm.stream()` for the async iterator.
|
|
5092
|
+
|
|
5093
|
+
When `llm` is an existing `ModelController`, it retains the security and load
|
|
5094
|
+
policy chosen when that controller was created. `createArcaneAI()` does not
|
|
5095
|
+
reapply its `loadPolicy` argument in that case, and supplying `security` with an
|
|
5096
|
+
existing controller throws `TypeError`. Provider input creates a new controller
|
|
5097
|
+
and applies the supplied `loadPolicy` and app-level `security` normally.
|
|
5098
|
+
|
|
5099
|
+
`createChatSession(options)` asynchronously imports the private managed
|
|
5100
|
+
`#arcane/persistent-ai-chat-session` specifier, resolves a
|
|
5101
|
+
`Promise<PersistentAIChatSession>`, and binds its `chat` function to this exact
|
|
5102
|
+
controller. Applications continue to use this public controller method rather
|
|
5103
|
+
than importing that private specifier. `options` must be a plain object and cannot contain
|
|
5104
|
+
`chat`. The resulting session preserves coherent live bounded context while
|
|
5105
|
+
letting each user/assistant/tool turn choose matching durable ChatEntity/DBOPFS
|
|
5106
|
+
persistence; `persist:false` does not write that turn to durable history or
|
|
5107
|
+
memory. There is no storage or provider fallback.
|
|
4996
5108
|
|
|
4997
5109
|
App and load-operation security use
|
|
4998
5110
|
`{security:{secure?:boolean, checks?:{byteLength?:boolean, sha256?:boolean}}}`.
|
|
@@ -5002,27 +5114,42 @@ binding scope, documented below, sits between those scopes.
|
|
|
5002
5114
|
|
|
5003
5115
|
### Availability and normalization
|
|
5004
5116
|
|
|
5005
|
-
**Browser.** It normalizes lifecycle,
|
|
5006
|
-
cancellation, completions, and structural tool-call
|
|
5007
|
-
selects a provider fallback nor executes an application
|
|
5117
|
+
**Browser.** It normalizes lifecycle, `statechange` and `progress` observation,
|
|
5118
|
+
lazy/manual use, cancellation, completions, and structural tool-call
|
|
5119
|
+
visibility. It neither selects a provider fallback nor executes an application
|
|
5120
|
+
tool. Persistent sessions additionally require ChatEntity/DBOPFS in the
|
|
5121
|
+
managed browser runtime.
|
|
5008
5122
|
|
|
5009
5123
|
### Example
|
|
5010
5124
|
|
|
5011
5125
|
```javascript
|
|
5012
5126
|
const ai = createArcaneAI({provider, loadPolicy:'manual'});
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5127
|
+
async function openLocalReviewAfterUserChoice() {
|
|
5128
|
+
const stop = ai.llm.on('progress', event => renderProgress(event.detail));
|
|
5129
|
+
try {
|
|
5130
|
+
await ai.load({offline:true});
|
|
5131
|
+
} finally {
|
|
5132
|
+
stop();
|
|
5133
|
+
}
|
|
5134
|
+
return ai.createChatSession({
|
|
5135
|
+
chatFileName:'local-review.jsonl',
|
|
5136
|
+
loadExisting:true
|
|
5137
|
+
});
|
|
5138
|
+
}
|
|
5016
5139
|
```
|
|
5017
5140
|
|
|
5018
5141
|
## createBrowserModelSource()
|
|
5019
5142
|
|
|
5020
5143
|
### Overview
|
|
5021
5144
|
|
|
5022
|
-
Validates a caller-owned model descriptor and creates the
|
|
5023
|
-
source accepted by the browser-WASM store/provider. The
|
|
5024
|
-
|
|
5025
|
-
|
|
5145
|
+
Validates a caller-owned ordered model-file descriptor and creates the
|
|
5146
|
+
cancellable HTTPS source accepted by the browser-WASM store/provider. The
|
|
5147
|
+
canonical descriptor is
|
|
5148
|
+
`{id,files:[{name?,url|immutableUrl,bytes?,sha256?},...]}`. The nonempty file
|
|
5149
|
+
array has unique normalized names and URLs. `bytes`, when present, is an
|
|
5150
|
+
expected positive safe-integer byte length, not inline data. The legacy
|
|
5151
|
+
one-file `{id,url|immutableUrl,name?,bytes?,sha256?}` shape remains accepted
|
|
5152
|
+
and normalizes to one ordered member.
|
|
5026
5153
|
|
|
5027
5154
|
### Signature and result
|
|
5028
5155
|
|
|
@@ -5030,17 +5157,18 @@ present, is the expected positive safe-integer byte length, not inline data.
|
|
|
5030
5157
|
createBrowserModelSource(descriptor, { fetchImpl=null }={})
|
|
5031
5158
|
```
|
|
5032
5159
|
|
|
5033
|
-
|
|
5160
|
+
Every URL must be absolute HTTPS with no credentials or fragment and no
|
|
5034
5161
|
revision-floating `main`, `master`, or `latest` path. A supplied SHA-256 value
|
|
5035
|
-
is exactly 64 hexadecimal characters. The frozen source exposes
|
|
5036
|
-
descriptor and `open({signal})
|
|
5037
|
-
|
|
5038
|
-
`
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5162
|
+
is exactly 64 hexadecimal characters. The frozen source exposes `kind`, the
|
|
5163
|
+
canonical descriptor fields, `descriptor`, and `open(memberIndex,{signal})`.
|
|
5164
|
+
For a one-file source, `open({signal})` remains accepted. The result is
|
|
5165
|
+
`{body,requestedUrl,finalUrl,reportedBytes,cancel}`. `reportedBytes` is the
|
|
5166
|
+
nullable valid nonnegative `Content-Length` observation; it is not an
|
|
5167
|
+
unconditional admission check. Every direct `open()` performs the configured
|
|
5168
|
+
fetch and does not admit bytes to the cache.
|
|
5169
|
+
|
|
5170
|
+
`immutableUrl` is an alias for `url`; both must match when supplied together.
|
|
5171
|
+
Legacy `licenseSpdx` and `sourceRevision` properties are not canonical
|
|
5044
5172
|
descriptor fields, runtime admission checks, or proof of license rights.
|
|
5045
5173
|
|
|
5046
5174
|
### Availability and normalization
|
|
@@ -5056,9 +5184,17 @@ corresponding effective check is enabled.
|
|
|
5056
5184
|
```javascript
|
|
5057
5185
|
const source = createBrowserModelSource({
|
|
5058
5186
|
id:'reviewed-model',
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5187
|
+
files:[{
|
|
5188
|
+
name:'model-q4-00001-of-00002.gguf',
|
|
5189
|
+
url:'https://models.example/revisions/4f7c/model-q4-00001-of-00002.gguf',
|
|
5190
|
+
bytes:123456789,
|
|
5191
|
+
sha256:'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
|
5192
|
+
},{
|
|
5193
|
+
name:'model-q4-00002-of-00002.gguf',
|
|
5194
|
+
url:'https://models.example/revisions/4f7c/model-q4-00002-of-00002.gguf',
|
|
5195
|
+
bytes:98765432,
|
|
5196
|
+
sha256:'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789'
|
|
5197
|
+
}]
|
|
5062
5198
|
});
|
|
5063
5199
|
```
|
|
5064
5200
|
|
|
@@ -5067,22 +5203,32 @@ const source = createBrowserModelSource({
|
|
|
5067
5203
|
### Overview
|
|
5068
5204
|
|
|
5069
5205
|
Creates the packaged Wllama provider from genuine source and store objects
|
|
5070
|
-
created by this module.
|
|
5071
|
-
`unloaded`, `loading`, `ready`,
|
|
5206
|
+
created by this module. Structural lookalikes are rejected. It serializes
|
|
5207
|
+
requests and exposes provider states `unloaded`, `loading`, `ready`,
|
|
5208
|
+
`unloading`, and `error`.
|
|
5072
5209
|
|
|
5073
5210
|
### Signature and result
|
|
5074
5211
|
|
|
5075
5212
|
```text
|
|
5076
|
-
createBrowserWasmLlmProvider({ source, store, loadDefaults={}, security, logger=console }={})
|
|
5213
|
+
createBrowserWasmLlmProvider({ source, sources, store, loadDefaults={}, security, logger=console }={})
|
|
5077
5214
|
```
|
|
5078
5215
|
|
|
5079
|
-
|
|
5080
|
-
`
|
|
5081
|
-
`
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5216
|
+
`sources` is a nonempty array of unique SDK-created sources. Optional legacy
|
|
5217
|
+
`source` names the default and must be one member of `sources`; when `sources`
|
|
5218
|
+
is omitted, `source` supplies the one-model catalog. The frozen provider
|
|
5219
|
+
exposes `protocol`, `id`, default `model`, `catalog`, `capabilities`, `status`,
|
|
5220
|
+
`load`, `unload`, `chat`, `stream`, `streamChat`, `use`, `probe`, and `dispose`.
|
|
5221
|
+
Direct `load()` selects a catalog model and returns `{model,status}`; the
|
|
5222
|
+
facade `ai.load()` returns the flat controller status. Load settings include
|
|
5223
|
+
offline mode, `AbortSignal`, progress, threads, and context/batch/micro-batch
|
|
5224
|
+
tokens. The runtime always forces `gpuLayers:99999`; callers cannot request CPU
|
|
5225
|
+
or partial offload.
|
|
5226
|
+
|
|
5227
|
+
Chat supports OpenAI-like message/generation fields, tools, tool choice,
|
|
5228
|
+
parallel tool-call preference, and JSON/JSON-Schema structured output.
|
|
5229
|
+
`stream()` returns a frozen async iterator with `result` and `cancel(reason)`.
|
|
5230
|
+
Returned tool calls are validated structural data with JSON-string arguments;
|
|
5231
|
+
the SDK never invokes a handler or executes a tool.
|
|
5086
5232
|
|
|
5087
5233
|
Provider `security` is the provider/model-binding scope. Security fields resolve
|
|
5088
5234
|
independently by precedence: load operation, provider/model binding, app SDK
|
|
@@ -5096,21 +5242,30 @@ requires unload and reload.
|
|
|
5096
5242
|
|
|
5097
5243
|
### Availability and normalization
|
|
5098
5244
|
|
|
5099
|
-
**Browser with WebAssembly
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5245
|
+
**Browser secure context with WebAssembly, OPFS/DBOPFS, WebGPU, and admitted
|
|
5246
|
+
full-offload/buffer/queue/fence evidence.** A load succeeds only after Wllama
|
|
5247
|
+
confirms the model is loaded and the full GPU execution evidence settles. There
|
|
5248
|
+
is no CPU fallback. Cross-origin isolation and coarse hardware fields remain
|
|
5249
|
+
observations rather than hard gates. Status discloses effective `security`,
|
|
5250
|
+
per-check `integrity`, catalog compatibility, storage evidence, and lifecycle
|
|
5251
|
+
state; unchecked bytes are never labeled SHA-256 verified. Adapter selection
|
|
5252
|
+
is instrumented as `arcane.ai.browser-wasm.webgpu.adapter.selected`.
|
|
5253
|
+
Cancellation normalizes to `ARCANE_AI_REQUEST_ABORTED`; load/admission failures
|
|
5254
|
+
surface stable `ARCANE_AI_*` codes such as `ARCANE_AI_WEBGPU_REQUIRED`,
|
|
5255
|
+
`ARCANE_AI_MODEL_FULL_OFFLOAD_UNPROVEN`, and
|
|
5256
|
+
`ARCANE_AI_MODEL_GPU_MEMORY_INSUFFICIENT`. Concurrent runtime inference can fail
|
|
5257
|
+
`ARCANE_AI_RUNTIME_BUSY`; inspection and status can report
|
|
5258
|
+
`ARCANE_AI_PROVIDER_UNAVAILABLE` or fallback `ARCANE_AI_RUNTIME_FAILED` without
|
|
5259
|
+
misrepresenting those observations as a successful load.
|
|
5105
5260
|
|
|
5106
5261
|
### Example
|
|
5107
5262
|
|
|
5108
5263
|
```javascript
|
|
5109
5264
|
const provider = createBrowserWasmLlmProvider({
|
|
5110
|
-
source,
|
|
5265
|
+
sources:[source],
|
|
5111
5266
|
store,
|
|
5112
5267
|
security:{secure:true},
|
|
5113
|
-
loadDefaults:{threads:1, contextTokens:4096
|
|
5268
|
+
loadDefaults:{threads:1, contextTokens:4096}
|
|
5114
5269
|
});
|
|
5115
5270
|
console.log(provider.status().state); // unloaded
|
|
5116
5271
|
```
|
|
@@ -5119,26 +5274,31 @@ console.log(provider.status().state); // unloaded
|
|
|
5119
5274
|
|
|
5120
5275
|
### Overview
|
|
5121
5276
|
|
|
5122
|
-
Adapts an existing DBOPFS instance into a model
|
|
5123
|
-
public methods. The adapter commits model
|
|
5124
|
-
`arcane.ai.browser-wasm.model.
|
|
5125
|
-
observed downloaded or cached byte
|
|
5277
|
+
Adapts an existing DBOPFS instance into a multi-model, ordered multi-file cache
|
|
5278
|
+
without renaming its public methods. The adapter commits every model file
|
|
5279
|
+
before the `arcane.ai.browser-wasm.model.v4` completion manifest and always
|
|
5280
|
+
records observed downloaded or cached byte lengths. A partial file set is not
|
|
5281
|
+
a cache hit.
|
|
5126
5282
|
|
|
5127
5283
|
### Signature and result
|
|
5128
5284
|
|
|
5129
5285
|
```text
|
|
5130
|
-
createDbopfsModelStore({ dbopfs, tableName='arcane_ai_browser_models' }={})
|
|
5286
|
+
createDbopfsModelStore({ dbopfs, tableName='arcane_ai_browser_models', estimateStorage=null }={})
|
|
5131
5287
|
```
|
|
5132
5288
|
|
|
5133
5289
|
The frozen result contains `kind`, `tableName`, the original `adapter`, and
|
|
5134
5290
|
`ready`, `openVerified`, `install`, `ensure`, and `remove`. `ensure()` returns
|
|
5135
|
-
the file
|
|
5136
|
-
`
|
|
5291
|
+
`files`, the one-file compatibility `file` or `null`, the manifest,
|
|
5292
|
+
`observedBytes`, integrity detail, storage evidence, and
|
|
5293
|
+
`cache:'cached'|'installed'`. Optional `estimateStorage()` supplies bounded
|
|
5294
|
+
quota evidence when the browser estimator is unavailable or the application
|
|
5295
|
+
owns a more precise view. `openVerified()` is a compatibility helper that
|
|
5137
5296
|
forces both checks on. Ordinary install/reuse compares expected length only
|
|
5138
5297
|
when effective `checks.byteLength` is true and hashes only when effective
|
|
5139
5298
|
`checks.sha256` is true. `offline:true` never downloads and rejects a miss with
|
|
5140
|
-
`ARCANE_AI_MODEL_OFFLINE_MISS`. Version-2
|
|
5141
|
-
|
|
5299
|
+
`ARCANE_AI_MODEL_OFFLINE_MISS`. Version-2/3 compatibility is internal; every
|
|
5300
|
+
new successful completion is recorded as version 4 without fabricating an
|
|
5301
|
+
integrity result.
|
|
5142
5302
|
|
|
5143
5303
|
### Availability and normalization
|
|
5144
5304
|
|
|
@@ -5146,17 +5306,398 @@ can migrate to version 3 without fabricating verification.
|
|
|
5146
5306
|
actually performed. Disabled byte-length checks do not compare descriptor
|
|
5147
5307
|
`bytes`, disabled SHA-256 checks do not hash or reread solely for a digest, and
|
|
5148
5308
|
overall integrity is `verified` when every enabled check succeeds or
|
|
5149
|
-
`unchecked` when neither check is enabled. Cache
|
|
5150
|
-
|
|
5151
|
-
|
|
5309
|
+
`unchecked` when neither check is enabled. Cache metadata is not a transferable
|
|
5310
|
+
capability or license proof. Provider unload/dispose keeps all cached files;
|
|
5311
|
+
`store.remove(source)` explicitly deletes that source's files and manifest.
|
|
5152
5312
|
|
|
5153
5313
|
### Example
|
|
5154
5314
|
|
|
5155
5315
|
```javascript
|
|
5156
5316
|
const store = createDbopfsModelStore({dbopfs});
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5317
|
+
async function verifyCachedModelAfterUserChoice() {
|
|
5318
|
+
await store.ready();
|
|
5319
|
+
const cached = await store.openVerified(source);
|
|
5320
|
+
console.log(cached ? 'verified cache' : 'cache miss');
|
|
5321
|
+
}
|
|
5322
|
+
```
|
|
5323
|
+
|
|
5324
|
+
## adaptV1LlmProvider()
|
|
5325
|
+
|
|
5326
|
+
### Overview
|
|
5327
|
+
|
|
5328
|
+
Projects one compatible admitted v1 browser-WASM provider into the provider-neutral
|
|
5329
|
+
LLM role consumed by the managed `arcane/AIProviderRuntime` projection. The
|
|
5330
|
+
runtime checks the v1 protocol, required identity/methods, and local-only
|
|
5331
|
+
capability; it does not establish SDK provenance for an arbitrary compatible
|
|
5332
|
+
object. The adapter does not
|
|
5333
|
+
change the wrapped provider, download a model, create a fallback, or execute a
|
|
5334
|
+
tool.
|
|
5335
|
+
|
|
5336
|
+
### Signature and result
|
|
5337
|
+
|
|
5338
|
+
```text
|
|
5339
|
+
adaptV1LlmProvider(provider)
|
|
5340
|
+
```
|
|
5341
|
+
|
|
5342
|
+
The frozen result is
|
|
5343
|
+
`{protocol:'arcane-ai-provider/2',role:'llm',id,localOnly:true,catalog,inspect,
|
|
5344
|
+
status,load,request,unload,dispose}`. `inspect()` returns an
|
|
5345
|
+
`arcane-ai-model-authority/1` record only for an exact catalog selection.
|
|
5346
|
+
`request()` accepts only the `chat` and `stream` operations, preserves
|
|
5347
|
+
structural tool calls, and never invokes application handlers. Re-adapting the
|
|
5348
|
+
same provider returns the same adapter object.
|
|
5349
|
+
|
|
5350
|
+
### Availability and normalization
|
|
5351
|
+
|
|
5352
|
+
**Browser; the wrapped provider retains its own secure-context, WebAssembly,
|
|
5353
|
+
OPFS/DBOPFS, WebGPU, model, and lifecycle requirements.** The adapter normalizes
|
|
5354
|
+
provider/2 selection and lifecycle without adding Node, native, cloud, network,
|
|
5355
|
+
or CPU fallback behavior.
|
|
5356
|
+
|
|
5357
|
+
### Example
|
|
5358
|
+
|
|
5359
|
+
```javascript
|
|
5360
|
+
import {adaptV1LlmProvider} from 'arcane-os/ai/browser-wasm';
|
|
5361
|
+
import {getAIProviderRuntime} from 'arcane/AIProviderRuntime';
|
|
5362
|
+
|
|
5363
|
+
const runtime = getAIProviderRuntime();
|
|
5364
|
+
const releaseProvider = runtime.register(adaptV1LlmProvider(provider));
|
|
5365
|
+
// Configure an exact llm route before load/use.
|
|
5366
|
+
releaseProvider();
|
|
5367
|
+
```
|
|
5368
|
+
|
|
5369
|
+
# Browser speech providers
|
|
5370
|
+
|
|
5371
|
+
`arcane-os/ai/browser-speech` exports exactly the five package members below.
|
|
5372
|
+
It ships provider, authority, artifact-store, and Worker mechanisms but no
|
|
5373
|
+
Whisper/Kokoro model weights, adapter runtime bytes, voices, download URLs,
|
|
5374
|
+
default catalog, CDN loader, native bridge, or cloud fallback. The providers
|
|
5375
|
+
implement `arcane-ai-provider/2`; the managed `arcane/AIProviderRuntime` and
|
|
5376
|
+
`arcane/AIRuntimeState` projection modules can normalize their independent
|
|
5377
|
+
role lifecycle and observation, but are not exports of this package subpath.
|
|
5378
|
+
|
|
5379
|
+
## BROWSER_SPEECH_ARTIFACT_PROTOCOL
|
|
5380
|
+
|
|
5381
|
+
### Overview
|
|
5382
|
+
|
|
5383
|
+
Stable protocol identifier for an SDK-created authenticated browser speech
|
|
5384
|
+
artifact store. It identifies the store contract, not a model authority,
|
|
5385
|
+
capability grant, or complete-cache receipt.
|
|
5386
|
+
|
|
5387
|
+
### Value and import
|
|
5388
|
+
|
|
5389
|
+
```text
|
|
5390
|
+
const BROWSER_SPEECH_ARTIFACT_PROTOCOL
|
|
5391
|
+
```
|
|
5392
|
+
|
|
5393
|
+
Its exact value is `arcane-ai-browser-speech-artifacts/1`, and it is exported
|
|
5394
|
+
only by `arcane-os/ai/browser-speech`.
|
|
5395
|
+
|
|
5396
|
+
### Availability and normalization
|
|
5397
|
+
|
|
5398
|
+
**Browser metadata.** Importing or reading the constant starts no Worker and
|
|
5399
|
+
downloads no model or runtime artifact. Store use additionally requires
|
|
5400
|
+
DBOPFS/OPFS, Web Locks, and the browser APIs described below.
|
|
5401
|
+
|
|
5402
|
+
### Example
|
|
5403
|
+
|
|
5404
|
+
```javascript
|
|
5405
|
+
import {
|
|
5406
|
+
BROWSER_SPEECH_ARTIFACT_PROTOCOL
|
|
5407
|
+
} from 'arcane-os/ai/browser-speech';
|
|
5408
|
+
|
|
5409
|
+
console.log(BROWSER_SPEECH_ARTIFACT_PROTOCOL);
|
|
5410
|
+
```
|
|
5411
|
+
|
|
5412
|
+
## createBrowserSpeechAuthority()
|
|
5413
|
+
|
|
5414
|
+
### Overview
|
|
5415
|
+
|
|
5416
|
+
Validates and freezes one caller-owned Whisper STT or Kokoro TTS model/runtime
|
|
5417
|
+
closure. The application owns every model, runtime, revision, URL, hash, voice,
|
|
5418
|
+
license, and business-policy choice; the SDK supplies no artifact selection.
|
|
5419
|
+
|
|
5420
|
+
### Signature and result
|
|
5421
|
+
|
|
5422
|
+
```text
|
|
5423
|
+
createBrowserSpeechAuthority({ providerId, role, model, runtime, security }={})
|
|
5424
|
+
```
|
|
5425
|
+
|
|
5426
|
+
`role` is exactly `stt` or `tts`. `model` supplies
|
|
5427
|
+
`{id,repository,revision,files}` and, for TTS, `defaultVoice`. `runtime`
|
|
5428
|
+
supplies `{adapter,version,revision,entry,files}`; the adapter is exactly
|
|
5429
|
+
`transformers-whisper` for STT or `kokoro-js` for TTS. File records use unique
|
|
5430
|
+
relative `path` and immutable HTTPS or same-origin `url` identities plus
|
|
5431
|
+
optional `bytes`, `sha256`, and `mediaType`. The runtime entry names one
|
|
5432
|
+
self-contained JavaScript module in the declared runtime closure.
|
|
5433
|
+
|
|
5434
|
+
The result is a frozen `arcane-ai-model-authority/1` record containing the
|
|
5435
|
+
provider/model/role identity, admitted local authority, normalized runtime and
|
|
5436
|
+
model file declarations, optional default voice, and normalized security policy.
|
|
5437
|
+
Construction binds declared identities; `store.prepare()` validates the actual
|
|
5438
|
+
downloaded or cached self-contained runtime graph before execution.
|
|
5439
|
+
|
|
5440
|
+
Security is the closed record
|
|
5441
|
+
`{secure?:boolean,checks?:{byteLength?:boolean,sha256?:boolean}}`. A provider
|
|
5442
|
+
resolves each field from SDK default `secure:false`, then `appSecurity`, provider
|
|
5443
|
+
`security`, and finally `load({security})`. Omitted checks default to the
|
|
5444
|
+
effective `secure` value, while explicit per-check booleans override it. Every
|
|
5445
|
+
enabled check requires matching `bytes` or `sha256` evidence on every runtime
|
|
5446
|
+
and model artifact and fails closed when evidence is absent or mismatched.
|
|
5447
|
+
Disabled checks are disclosed and are never reported as verification.
|
|
5448
|
+
|
|
5449
|
+
### Availability and normalization
|
|
5450
|
+
|
|
5451
|
+
**Browser descriptor construction; actual use requires the chosen artifact
|
|
5452
|
+
store and provider Web APIs.** Mutable `main`, `master`, and `latest` paths,
|
|
5453
|
+
credentials, fragments, duplicate identities, mismatched adapters, and runtime
|
|
5454
|
+
graphs outside the declared closure fail closed. This function grants no
|
|
5455
|
+
publisher authenticity or license rights.
|
|
5456
|
+
|
|
5457
|
+
### Example
|
|
5458
|
+
|
|
5459
|
+
```javascript
|
|
5460
|
+
import {createBrowserSpeechAuthority} from 'arcane-os/ai/browser-speech';
|
|
5461
|
+
|
|
5462
|
+
const authority = createBrowserSpeechAuthority({
|
|
5463
|
+
providerId:'review-whisper',
|
|
5464
|
+
role:'stt',
|
|
5465
|
+
model:{
|
|
5466
|
+
id:'review-whisper-model',
|
|
5467
|
+
repository:'caller-models',
|
|
5468
|
+
revision:'model-r1',
|
|
5469
|
+
files:[{
|
|
5470
|
+
path:'model.onnx',
|
|
5471
|
+
url:'https://models.example/model-r1/model.onnx'
|
|
5472
|
+
}]
|
|
5473
|
+
},
|
|
5474
|
+
runtime:{
|
|
5475
|
+
adapter:'transformers-whisper',
|
|
5476
|
+
version:'1.0.0',
|
|
5477
|
+
revision:'runtime-r1',
|
|
5478
|
+
entry:'adapter.mjs',
|
|
5479
|
+
files:[{
|
|
5480
|
+
path:'adapter.mjs',
|
|
5481
|
+
url:'https://runtime.example/runtime-r1/adapter.mjs',
|
|
5482
|
+
mediaType:'text/javascript'
|
|
5483
|
+
}]
|
|
5484
|
+
}
|
|
5485
|
+
});
|
|
5486
|
+
```
|
|
5487
|
+
|
|
5488
|
+
## createDbopfsSpeechArtifactStore()
|
|
5489
|
+
|
|
5490
|
+
### Overview
|
|
5491
|
+
|
|
5492
|
+
Adapts an existing DBOPFS instance into an authority-scoped speech
|
|
5493
|
+
runtime/model store. It serializes each exact authority with an exclusive Web
|
|
5494
|
+
Lock, removes partial state after failure, and commits the
|
|
5495
|
+
`arcane.ai.browser-speech.assets.v1` completion manifest only after every
|
|
5496
|
+
declared file succeeds.
|
|
5497
|
+
|
|
5498
|
+
### Signature and result
|
|
5499
|
+
|
|
5500
|
+
```text
|
|
5501
|
+
createDbopfsSpeechArtifactStore({ dbopfs, tableName='arcane_ai_browser_speech', fetchImpl=null, objectUrlFactory=null }={})
|
|
5502
|
+
```
|
|
5503
|
+
|
|
5504
|
+
The frozen result is `{protocol,tableName,prepare,remove}`.
|
|
5505
|
+
`prepare(authority,{signal,onProgress,offline=false,security})` admits a
|
|
5506
|
+
compatible complete cache or downloads every declared file with omitted
|
|
5507
|
+
credentials, enforces only enabled byte-length/SHA-256 checks, validates the
|
|
5508
|
+
closed runtime graph, materializes object URLs, and returns
|
|
5509
|
+
`{cache,runtime,model,release}`. Call `release()` when the Worker no longer
|
|
5510
|
+
needs those URLs. `offline:true` never fetches and rejects a miss with
|
|
5511
|
+
`ARCANE_AI_ARTIFACT_OFFLINE_MISS`. `remove(authority)` deletes that exact
|
|
5512
|
+
authority's files and manifest.
|
|
5513
|
+
|
|
5514
|
+
### Availability and normalization
|
|
5515
|
+
|
|
5516
|
+
**Browser with a ready DBOPFS instance, OPFS, Web Locks, Fetch or an injected
|
|
5517
|
+
fetch function, File/Blob, and object URLs.** An unavailable authority lock
|
|
5518
|
+
fails as `ARCANE_AI_STORAGE_BUSY`; download, integrity, cache, graph, and
|
|
5519
|
+
storage failures remain observable `ARCANE_AI_*` errors. Completion metadata
|
|
5520
|
+
is cache-consistency evidence, not transferable authority or publisher proof.
|
|
5521
|
+
|
|
5522
|
+
### Example
|
|
5523
|
+
|
|
5524
|
+
```javascript
|
|
5525
|
+
import {
|
|
5526
|
+
createDbopfsSpeechArtifactStore
|
|
5527
|
+
} from 'arcane-os/ai/browser-speech';
|
|
5528
|
+
|
|
5529
|
+
const speechStore = createDbopfsSpeechArtifactStore({dbopfs});
|
|
5530
|
+
async function inspectCachedSpeechAfterUserChoice() {
|
|
5531
|
+
// This strict offline call assumes this exact authority was admitted earlier.
|
|
5532
|
+
const prepared = await speechStore.prepare(authority, {offline:true});
|
|
5533
|
+
try {
|
|
5534
|
+
console.log(prepared.cache, prepared.runtime.entry);
|
|
5535
|
+
} finally {
|
|
5536
|
+
prepared.release();
|
|
5537
|
+
}
|
|
5538
|
+
}
|
|
5539
|
+
```
|
|
5540
|
+
|
|
5541
|
+
## createBrowserWhisperProvider()
|
|
5542
|
+
|
|
5543
|
+
### Overview
|
|
5544
|
+
|
|
5545
|
+
Creates a local-only Whisper speech-to-text provider for the provider-neutral
|
|
5546
|
+
AI runtime. It owns one independent STT load/use/unload/dispose lifecycle and
|
|
5547
|
+
never selects a cloud, native, or LLM fallback.
|
|
5548
|
+
|
|
5549
|
+
### Signature and result
|
|
5550
|
+
|
|
5551
|
+
```text
|
|
5552
|
+
createBrowserWhisperProvider(options={})
|
|
5553
|
+
```
|
|
5554
|
+
|
|
5555
|
+
The recognized options are
|
|
5556
|
+
`{id='arcane-browser-whisper',localOnly=true,model,runtime,appSecurity,
|
|
5557
|
+
security,store,offline=false}`. The frozen result is
|
|
5558
|
+
`{protocol:'arcane-ai-provider/2',role:'stt',id,localOnly:true,catalog,inspect,
|
|
5559
|
+
status,load,request,unload,dispose}`. The only request operation is
|
|
5560
|
+
`transcribe`; its payload is `{audio:Float32Array,sampleRate:16000}`. The
|
|
5561
|
+
Worker-transferred result is a structured `{text}` record; the client does not
|
|
5562
|
+
re-freeze the cloned record.
|
|
5563
|
+
|
|
5564
|
+
`status()` returns
|
|
5565
|
+
`{role,providerId,modelId,state,loaded,busy,generation,errorCode,cache}`.
|
|
5566
|
+
States are `unloaded`, `loading`, `ready`, `unloading`, `error`, and
|
|
5567
|
+
`disposed`. Compatible concurrent loads coalesce; concurrent requests fail as
|
|
5568
|
+
`ARCANE_AI_PROVIDER_BUSY`. Cancellation after the Worker request begins
|
|
5569
|
+
terminates that Worker slot, returns the provider to `unloaded`, and rejects as
|
|
5570
|
+
`ARCANE_AI_REQUEST_ABORTED`. Cancellation while shared Blob/File audio is still
|
|
5571
|
+
being decoded occurs before Worker use; it rejects with the same code while the
|
|
5572
|
+
loaded Worker remains intact and the provider stays `ready`.
|
|
5573
|
+
|
|
5574
|
+
The provider also accepts the shared AI speech payload
|
|
5575
|
+
`{audio:Blob|File,mimeType,model}`. It requires an exact model match, validates
|
|
5576
|
+
the MIME essence against `Blob.type`, decodes through browser audio APIs, and
|
|
5577
|
+
copies authoritative 16 kHz mono `Float32Array` PCM into the same native
|
|
5578
|
+
provider operation. Missing decode support fails
|
|
5579
|
+
`ARCANE_AI_AUDIO_DECODE_UNAVAILABLE`; invalid or failed decoding fails
|
|
5580
|
+
`ARCANE_AI_INVALID_REQUEST` or `ARCANE_AI_AUDIO_DECODE_FAILED`. Unknown fields
|
|
5581
|
+
and accessors are rejected before Worker use.
|
|
5582
|
+
|
|
5583
|
+
### Availability and normalization
|
|
5584
|
+
|
|
5585
|
+
**Browser with DBOPFS, Web Locks, Workers, object URLs, and a caller-admitted
|
|
5586
|
+
self-contained `transformers-whisper` runtime/model closure.** The subpath is
|
|
5587
|
+
importable in Node, but no Node storage, Worker, audio-decoder, or speech
|
|
5588
|
+
execution adapter is published. No Core speech call, model/runtime download
|
|
5589
|
+
authority, or automatic provider fallback is added. Provider objects are not event targets; register them with
|
|
5590
|
+
the managed AI provider runtime when normalized `AIRuntimeState` observation is
|
|
5591
|
+
needed.
|
|
5592
|
+
|
|
5593
|
+
### Example
|
|
5594
|
+
|
|
5595
|
+
```javascript
|
|
5596
|
+
import {createBrowserWhisperProvider} from 'arcane-os/ai/browser-speech';
|
|
5597
|
+
|
|
5598
|
+
const whisper = createBrowserWhisperProvider({model, runtime, store:speechStore});
|
|
5599
|
+
async function transcribeAfterUserChoice(audioBlob) {
|
|
5600
|
+
await whisper.load({
|
|
5601
|
+
role:'stt',
|
|
5602
|
+
selection:{
|
|
5603
|
+
providerId:whisper.id,
|
|
5604
|
+
modelId:whisper.catalog()[0].id,
|
|
5605
|
+
localOnly:true
|
|
5606
|
+
},
|
|
5607
|
+
progress() {}
|
|
5608
|
+
});
|
|
5609
|
+
const transcript = await whisper.request({
|
|
5610
|
+
role:'stt',
|
|
5611
|
+
operation:'transcribe',
|
|
5612
|
+
payload:{
|
|
5613
|
+
audio:audioBlob,
|
|
5614
|
+
mimeType:audioBlob.type,
|
|
5615
|
+
model:whisper.catalog()[0].id
|
|
5616
|
+
}
|
|
5617
|
+
});
|
|
5618
|
+
console.log(transcript.text);
|
|
5619
|
+
}
|
|
5620
|
+
```
|
|
5621
|
+
|
|
5622
|
+
## createBrowserKokoroProvider()
|
|
5623
|
+
|
|
5624
|
+
### Overview
|
|
5625
|
+
|
|
5626
|
+
Creates a local-only Kokoro text-to-speech provider for the provider-neutral AI
|
|
5627
|
+
runtime. It owns one independent TTS lifecycle and never selects a cloud,
|
|
5628
|
+
native, or LLM fallback.
|
|
5629
|
+
|
|
5630
|
+
### Signature and result
|
|
5631
|
+
|
|
5632
|
+
```text
|
|
5633
|
+
createBrowserKokoroProvider(options={})
|
|
5634
|
+
```
|
|
5635
|
+
|
|
5636
|
+
The recognized options are
|
|
5637
|
+
`{id='arcane-browser-kokoro',localOnly=true,model,runtime,appSecurity,security,
|
|
5638
|
+
store,offline=false}`. The frozen result is
|
|
5639
|
+
`{protocol:'arcane-ai-provider/2',role:'tts',id,localOnly:true,catalog,inspect,
|
|
5640
|
+
status,load,request,unload,dispose}`. The only request operation is
|
|
5641
|
+
`synthesize`; its payload is `{text,voice?,speed=1}`. Omitted `voice` uses the
|
|
5642
|
+
caller-supplied `model.defaultVoice`; `speed` is greater than zero and at most
|
|
5643
|
+
four. The Worker-transferred result is a structured
|
|
5644
|
+
`{audio:Float32Array,sampleRate:24000,voice}` record; the client does not
|
|
5645
|
+
re-freeze the cloned record.
|
|
5646
|
+
|
|
5647
|
+
The shared AI request form is
|
|
5648
|
+
`{model,input,responseFormat,voice?,speed?}`. It requires the exact model,
|
|
5649
|
+
admits only `responseFormat:'wav'`, maps `input` to provider-native text, and
|
|
5650
|
+
returns frozen `{audio:Uint8Array,contentType:'audio/wav'}` containing 24 kHz
|
|
5651
|
+
mono 16-bit PCM. Unsupported formats fail
|
|
5652
|
+
`ARCANE_AI_UNSUPPORTED_RESPONSE_FORMAT`; malformed adapter audio fails
|
|
5653
|
+
`ARCANE_AI_INVALID_PROVIDER_RESULT`. Unknown fields and accessors fail closed.
|
|
5654
|
+
|
|
5655
|
+
Lifecycle/status, coalesced load, busy-request, unload, Worker-failure, and
|
|
5656
|
+
disposal behavior matches the Whisper provider. Cancellation after Worker use
|
|
5657
|
+
begins unloads that Worker; cancellation before Worker use rejects while the
|
|
5658
|
+
provider stays ready. Stable failures include
|
|
5659
|
+
`ARCANE_AI_INVALID_REQUEST`, `ARCANE_AI_NOT_READY`,
|
|
5660
|
+
`ARCANE_AI_PROVIDER_DISPOSED`, `ARCANE_AI_OPERATION_SUPERSEDED`,
|
|
5661
|
+
`ARCANE_AI_WORKER_CRASHED`, `ARCANE_AI_WORKER_MESSAGE_ERROR`, and
|
|
5662
|
+
`ARCANE_AI_ADAPTER_PROTOCOL_MISMATCH`.
|
|
5663
|
+
|
|
5664
|
+
### Availability and normalization
|
|
5665
|
+
|
|
5666
|
+
**Browser with DBOPFS, Web Locks, Workers, object URLs, and a caller-admitted
|
|
5667
|
+
self-contained `kokoro-js` runtime/model/voice closure.** The subpath is
|
|
5668
|
+
importable in Node, but no Node storage, Worker, or speech execution adapter is
|
|
5669
|
+
published. No Core speech call, model/runtime/voice authority, or automatic provider fallback is
|
|
5670
|
+
added. Provider objects are not event targets; managed `AIProviderRuntime` and
|
|
5671
|
+
`AIRuntimeState` projections own normalized cross-role observation.
|
|
5672
|
+
|
|
5673
|
+
### Example
|
|
5674
|
+
|
|
5675
|
+
```javascript
|
|
5676
|
+
import {createBrowserKokoroProvider} from 'arcane-os/ai/browser-speech';
|
|
5677
|
+
|
|
5678
|
+
const kokoro = createBrowserKokoroProvider({model, runtime, store:speechStore});
|
|
5679
|
+
async function synthesizeAfterUserChoice() {
|
|
5680
|
+
await kokoro.load({
|
|
5681
|
+
role:'tts',
|
|
5682
|
+
selection:{
|
|
5683
|
+
providerId:kokoro.id,
|
|
5684
|
+
modelId:kokoro.catalog()[0].id,
|
|
5685
|
+
localOnly:true
|
|
5686
|
+
},
|
|
5687
|
+
progress() {}
|
|
5688
|
+
});
|
|
5689
|
+
const speech = await kokoro.request({
|
|
5690
|
+
role:'tts',
|
|
5691
|
+
operation:'synthesize',
|
|
5692
|
+
payload:{
|
|
5693
|
+
model:kokoro.catalog()[0].id,
|
|
5694
|
+
input:'Hello from Arcane.',
|
|
5695
|
+
responseFormat:'wav',
|
|
5696
|
+
speed:1
|
|
5697
|
+
}
|
|
5698
|
+
});
|
|
5699
|
+
console.log(speech.audio, speech.contentType);
|
|
5700
|
+
}
|
|
5160
5701
|
```
|
|
5161
5702
|
|
|
5162
5703
|
## Data export subpaths
|