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
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
# Protocol and host architecture
|
|
2
|
+
|
|
3
|
+
This is the deep reference behind the compact availability notes elsewhere.
|
|
4
|
+
Application developers should start with the
|
|
5
|
+
[availability and normalization guide](availability-and-normalization.md), call
|
|
6
|
+
one documented API, and treat the protocols below as implementation detail.
|
|
7
|
+
|
|
8
|
+
## Layer map
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
application code
|
|
12
|
+
|-- Node SDK API ----------------- arcane-cli-events/1 + SDK results
|
|
13
|
+
|-- EventManager ----------------- synchronous bus + arcane-event-stack/1
|
|
14
|
+
|-- browser-local AI ------------- WebGPU/WASM/Workers/DBOPFS; no Core grant
|
|
15
|
+
`-- globalThis.Arcane
|
|
16
|
+
|-- development host -------- development HTTP bridge
|
|
17
|
+
|-- Microsoft NT native ----- WebView2 host bridge
|
|
18
|
+
|-- Linux native ------------ WebKitGTK host bridge
|
|
19
|
+
`-- Android native ---------- Android WebView message bridge
|
|
20
|
+
|
|
|
21
|
+
`-- Arcane Core/provider boundary
|
|
22
|
+
|-- platform services
|
|
23
|
+
|-- ArcaneOllama loopback service
|
|
24
|
+
`-- explicitly selected cloud APIs
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Each downward boundary can add authority and platform capability. None can be
|
|
28
|
+
inferred merely from a function existing in shared JavaScript.
|
|
29
|
+
|
|
30
|
+
## SDK package and CLI protocols
|
|
31
|
+
|
|
32
|
+
The npm package API is ordinary Node.js ESM. The CLI and programmatic toolchain
|
|
33
|
+
share one headless operation implementation. Long-running operations accept
|
|
34
|
+
before blocking work, own their task, stream structured events with bounded
|
|
35
|
+
backpressure, emit progress or heartbeats, support cancellation where the
|
|
36
|
+
underlying operation can do so safely, and surface failure through rejection or
|
|
37
|
+
a nonzero CLI status.
|
|
38
|
+
|
|
39
|
+
Machine output uses `arcane-cli-events/1`. Native planning and providers use:
|
|
40
|
+
|
|
41
|
+
- `arcane-target-adapter/1` for target adapters;
|
|
42
|
+
- `arcane-native-build-plan/1` for single-attempt native plans;
|
|
43
|
+
- `arcane-native-builder/1` for injected native builders;
|
|
44
|
+
- `arcane-integrated-toolchain/1` for the fixed integrated shared/Core provider.
|
|
45
|
+
|
|
46
|
+
These protocols normalize orchestration and results. They do not normalize a
|
|
47
|
+
Windows EXE, Linux DEB, Android APK, and portable directory into the same
|
|
48
|
+
artifact kind.
|
|
49
|
+
|
|
50
|
+
Managed browser imports have three supported control-plane entrypoints. The CLI
|
|
51
|
+
uses `arcane import-map`; Node callers use
|
|
52
|
+
`executeOperation('import-map', options)` or
|
|
53
|
+
`createToolchain(defaults).importMap(options)`. These are three routes to the
|
|
54
|
+
same app-scoped operation, not three import-map formats. Each route discovers
|
|
55
|
+
the selected descriptor's directly navigable admitted `.html`/`.htm` documents
|
|
56
|
+
through the package include/exclude rules and writes one canonical map to the
|
|
57
|
+
artifact plus every such document. The current marker is exactly one matching
|
|
58
|
+
`meta[name="arcane-app-id"]`; an unmarked secondary page with an active `base`
|
|
59
|
+
remains admitted under the current secondary-document rule. Wrong or duplicate
|
|
60
|
+
explicit identity fails, and the selected page then must pass exact path-relative
|
|
61
|
+
base validation.
|
|
62
|
+
Included HTML with neither signal is a component fragment and remains a
|
|
63
|
+
complete package file.
|
|
64
|
+
`arcane-os/preference-store` and
|
|
65
|
+
`arcane-os/speech-playback` are the two portable runtime subpaths: Node package
|
|
66
|
+
exports and managed browser keys both resolve directly to the canonical runtime
|
|
67
|
+
module namespaces, while `arcane/PreferenceStore` and
|
|
68
|
+
`arcane/SpeechPlayback` are the established browser import-map names. There is
|
|
69
|
+
no exported `importMapApplication()` function, `generateImportMap()` function, or
|
|
70
|
+
`arcane-os/import-map` package subpath.
|
|
71
|
+
|
|
72
|
+
The application dependency boundary is conditional. Only an application that
|
|
73
|
+
actually consumes Arcane declares one exact published `arcane-os` version in
|
|
74
|
+
its own `package.json` and resolves it through that project's normal install
|
|
75
|
+
into its own `node_modules`. An application that does not currently consume
|
|
76
|
+
Arcane adds no `arcane-os` dependency solely because of this rule; the user or
|
|
77
|
+
governing task may direct that application to adopt Arcane later, at which point
|
|
78
|
+
the same app-owned package, install, projection, and artifact boundary applies.
|
|
79
|
+
An Arcane consumer never depends on a global install, link or symlink, or
|
|
80
|
+
another Arcane OS/SDK checkout. The explicit `--sdk-runtime-source` checkout is
|
|
81
|
+
a temporary development server input only: its path and mutable authority are
|
|
82
|
+
not persisted in application package metadata, lockfiles, managed import maps,
|
|
83
|
+
or `dist`. Distribution instead uses the app's installed package and
|
|
84
|
+
materializes the complete required SDK runtime,
|
|
85
|
+
browser-runtime, and managed-import-map closure inside that app's own artifact.
|
|
86
|
+
No application polls for SDK changes.
|
|
87
|
+
|
|
88
|
+
## Installed SDK runtime materialization
|
|
89
|
+
|
|
90
|
+
`materializeInstalledSdkRuntime()` is the Node entrypoint for refreshing one
|
|
91
|
+
external workspace's checked-in `arcane/` projection from its one exact
|
|
92
|
+
installed SDK declaration. Import the function through the dependency key that
|
|
93
|
+
the workspace actually declares: `arcane-os` for the canonical package name or,
|
|
94
|
+
for example, `arcane-sdk` for the exact `npm:arcane-os@<version>` alias. No
|
|
95
|
+
application- or Arcane OS-local copier owns this operation.
|
|
96
|
+
|
|
97
|
+
The operation resolves that declaration while holding the shared
|
|
98
|
+
workspace-operation lock, copies the complete runtime and browser-runtime
|
|
99
|
+
content, and returns the installed-package location plus the materialized
|
|
100
|
+
workspace runtime paths. After the complete runtime replacement, it writes or
|
|
101
|
+
replaces semantic `arcane.lock.json` metadata from the actual installed
|
|
102
|
+
dependency name, package name, package version, and alias source.
|
|
103
|
+
|
|
104
|
+
Materialization writes a complete staging tree before the commit boundary,
|
|
105
|
+
moves any prior runtime to an owned backup, installs the new tree, and restores
|
|
106
|
+
the prior tree if commit fails. Cancellation remains effective through the last
|
|
107
|
+
pre-commit check. Successful whole-tree replacement removes paths absent from
|
|
108
|
+
the selected runtime content. The lock document describes the selected
|
|
109
|
+
installation and projected roots; it is not a content-identity or admission
|
|
110
|
+
record.
|
|
111
|
+
|
|
112
|
+
`upgradeApplication()` and `arcane upgrade` run the application's ordinary
|
|
113
|
+
`npm upgrade` command. They do not independently reconcile the installed SDK
|
|
114
|
+
projection, semantic Arcane lock, or managed import map.
|
|
115
|
+
|
|
116
|
+
## Central events and time-travel data
|
|
117
|
+
|
|
118
|
+
`arcane-os/event-manager` is host-neutral JavaScript. Its live event path is
|
|
119
|
+
synchronous, in-process `event-pubsub`; it does not select WebView2,
|
|
120
|
+
WebKitGTK, Android, HTTP, Core, or a kernel boundary. Optional history uses the
|
|
121
|
+
`arcane-event-stack/1` data format. That protocol names a diagnostic document,
|
|
122
|
+
not a network channel and not the `arcane/1` Core RPC
|
|
123
|
+
protocol.
|
|
124
|
+
|
|
125
|
+
Live listeners receive the original arguments. Recording separately snapshots
|
|
126
|
+
complete payloads and metadata while redacting credentials and explicitly
|
|
127
|
+
protected private fields. Exported stacks can be moved between Node and browser
|
|
128
|
+
hosts because `parseEventStack()` rejects genuinely malformed data before
|
|
129
|
+
playback. Review mode emits records, events mode deliberately
|
|
130
|
+
re-emits recorded event types, and neither mode restores external host side
|
|
131
|
+
effects or DOM state.
|
|
132
|
+
|
|
133
|
+
<details>
|
|
134
|
+
<summary>Event-stack structure and privacy boundary</summary>
|
|
135
|
+
|
|
136
|
+
Each document carries `protocol`, `sessionId`, `createdAt`, and ordered
|
|
137
|
+
`events`. Each record repeats the protocol/session and carries sequence,
|
|
138
|
+
timing, nesting/causation, source/category, payload, metadata, status, and
|
|
139
|
+
failure evidence. Recording retains the complete selected session until the
|
|
140
|
+
caller clears it or disables recording. Import rejects genuinely malformed or
|
|
141
|
+
unsafe structure and grants no Core capability or provider authority.
|
|
142
|
+
|
|
143
|
+
</details>
|
|
144
|
+
|
|
145
|
+
See [EventManager and time-travel review](event-manager.md) for the callable
|
|
146
|
+
surface, DOM privacy defaults, playback modes, and recovery behavior.
|
|
147
|
+
|
|
148
|
+
## Browser runtime delivery
|
|
149
|
+
|
|
150
|
+
External and modern integrated workspaces keep the same application URLs and a
|
|
151
|
+
browser-standard import map. Each selected app owns
|
|
152
|
+
`apps/<id>/modules/arcane.importmap.json`; the exact canonical JSON is also
|
|
153
|
+
embedded in its HTML entry as a managed `<script type="importmap"
|
|
154
|
+
data-arcane-import-map>`. The map follows `<base>` and precedes module scripts,
|
|
155
|
+
classic scripts, and module preloads, so application code can use stable named
|
|
156
|
+
imports such as:
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
import ollama from 'arcane/Ollama';
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The physical-v1 tree lives entirely beneath `arcane/`. SDK `0.5.11` projects the
|
|
163
|
+
complete canonical runtime and browser runtime selected by the installed SDK
|
|
164
|
+
package. Runtime dependencies stay under
|
|
165
|
+
`arcane/dependencies/`; the SDK event and browser-AI closure stays under
|
|
166
|
+
`arcane/sdk/`. This URL-key separation prevents runtime and SDK dependency
|
|
167
|
+
versions from aliasing one another.
|
|
168
|
+
|
|
169
|
+
The physical workspace route keeps its established route count and order. The
|
|
170
|
+
external route includes `components`, `css`, `dependencies`, `entities`, `img`,
|
|
171
|
+
`modules`, and `sdk`, followed by optional trailing `security` when that
|
|
172
|
+
directory exists; its external license route remains second. The modern
|
|
173
|
+
integrated physical route uses the same ordered include list in its one route.
|
|
174
|
+
Omitting only that final optional entry is compatible. Removing, reordering, or
|
|
175
|
+
renaming any preceding entry changes the physical contract.
|
|
176
|
+
|
|
177
|
+
The `0.5.11` map derives its complete entries from the selected runtime graph;
|
|
178
|
+
application source imports do not select a fixed entry count. The operation
|
|
179
|
+
result reports `imports`, `entryCount`, and `excludedModules`; reached-file
|
|
180
|
+
traversal remains internal. The
|
|
181
|
+
managed graph exposes `arcane-os/event-manager`, `arcane-os/ai/browser-wasm`,
|
|
182
|
+
`arcane-os/ai/browser-speech`, `arcane-os/preference-store`, and
|
|
183
|
+
`arcane-os/speech-playback`; dependency compatibility mappings are added when
|
|
184
|
+
runtime or SDK root traversal observes them.
|
|
185
|
+
|
|
186
|
+
The focused physical targets remain stable when their bindings are reached:
|
|
187
|
+
|
|
188
|
+
| Browser specifier | Physical target |
|
|
189
|
+
| --- | --- |
|
|
190
|
+
| `arcane-os/event-manager` | `./arcane/sdk/event-manager.mjs` |
|
|
191
|
+
| `arcane-os/ai/browser-wasm` | `./arcane/sdk/ai/browser-wasm.mjs` |
|
|
192
|
+
| `arcane-os/ai/browser-speech` | `./arcane/sdk/ai/browser-speech.mjs` |
|
|
193
|
+
| `arcane-os/preference-store` | `./arcane/modules/PreferenceStore.js` |
|
|
194
|
+
| `arcane-os/speech-playback` | `./arcane/modules/SpeechPlayback.js` |
|
|
195
|
+
| `event-pubsub` | `./arcane/sdk/dependencies/event-pubsub/index.js` |
|
|
196
|
+
| `./node_modules/strong-type/index.js` | `./arcane/dependencies/strong-type/index.js` |
|
|
197
|
+
|
|
198
|
+
There is no `arcane-os` package-root mapping, bare `strong-type` mapping, or
|
|
199
|
+
catch-all `arcane/` prefix. Classic scripts, workers, stylesheets, and other
|
|
200
|
+
non-ESM assets use their documented URL or host loading contract rather than
|
|
201
|
+
invented package bindings. Development serves the selected app plus the
|
|
202
|
+
complete selected tree.
|
|
203
|
+
Packaging copies the same map, app entry, and physical content into `dist/<id>`;
|
|
204
|
+
targets never resolve through the consumer workspace's root `node_modules/`.
|
|
205
|
+
The two lowercase static runtime package specifiers above are also exact npm
|
|
206
|
+
package exports, so Node and managed-browser source can share those specifiers
|
|
207
|
+
without data URLs, copied modules, or a consumer-owned loader.
|
|
208
|
+
|
|
209
|
+
`generateImportMap()` is an internal toolchain operation, not a package export.
|
|
210
|
+
The shared app-document owner derives the configured entry plus the
|
|
211
|
+
deterministic admitted `.html`/`.htm` inventory from the descriptor's package
|
|
212
|
+
include/exclude rules. `import-map`, development, and packaging all reuse that
|
|
213
|
+
discovery. One transaction writes the artifact and the same managed
|
|
214
|
+
JSON into every selected document. The result reports
|
|
215
|
+
`documentPaths`, `documentCount`, and `files`: artifact first, configured entry
|
|
216
|
+
second, then additional documents as `role:"document"`. The public CLI keeps
|
|
217
|
+
its existing two-option command; callers never maintain a separate page list.
|
|
218
|
+
|
|
219
|
+
An external package and development server expose the runtime
|
|
220
|
+
inventory at `/ARCANE_RUNTIME_PROJECTION.json`:
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
{
|
|
224
|
+
schemaVersion: 1,
|
|
225
|
+
kind: 'arcane-app-runtime-projection',
|
|
226
|
+
sdkVersion,
|
|
227
|
+
pathPrefix: 'arcane/',
|
|
228
|
+
files: [{path}]
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The projection contains the complete public paths relative to its declared
|
|
233
|
+
`pathPrefix:'arcane/'` (for example, `modules/...` and `sdk/...`). It does not
|
|
234
|
+
expose the private `/ARCANE_APP_RELEASE.json`. Genuinely malformed projection
|
|
235
|
+
data fails `ARCANE_RUNTIME_PROJECTION_INVALID`.
|
|
236
|
+
|
|
237
|
+
External `validateWorkspace()` results also expose `sdkInstallation` with
|
|
238
|
+
exactly `dependencyName`, `packageSource`,
|
|
239
|
+
`canonicalPackageRoot`, `packageName`, `packageVersion`, `runtimeRoot`,
|
|
240
|
+
and `browserRuntimeRoot`. A
|
|
241
|
+
workspace may use the canonical dependency name or one exact npm alias such as
|
|
242
|
+
`npm:arcane-os@0.5.11`; the physical package manifest must still identify
|
|
243
|
+
exactly as `arcane-os@0.5.11`. Canonical-plus-alias duplicates, multiple aliases,
|
|
244
|
+
links/junctions, indirect package roots, or version drift are reported.
|
|
245
|
+
|
|
246
|
+
For external workspaces, `arcane dev` serves the projected `arcane/` root,
|
|
247
|
+
including `arcane/sdk` and `arcane/dependencies`, alongside the selected
|
|
248
|
+
application. Integrated workspaces retain their configured physical routes.
|
|
249
|
+
The explicit live-source development mapping remains a separate development
|
|
250
|
+
path and does not rewrite the installed projection.
|
|
251
|
+
|
|
252
|
+
The imported module can be pure browser logic, standard-Web-API logic, or a
|
|
253
|
+
client of `globalThis.Arcane`. Import-map resolution is not a new Arcane wire
|
|
254
|
+
protocol, Core capability, network authority, or provider fallback. Import
|
|
255
|
+
transport and host RPC remain separate layers.
|
|
256
|
+
|
|
257
|
+
<details>
|
|
258
|
+
<summary>Refresh lifecycle and managed-file commit behavior</summary>
|
|
259
|
+
|
|
260
|
+
Scaffolding (`new` and `init`) creates the map. `dev` refreshes once before
|
|
261
|
+
binding. `import-map` refreshes every admitted document explicitly.
|
|
262
|
+
Non-dry-run `package`, browser `build`, and paired native packaging refresh
|
|
263
|
+
before collecting source. Packaging does not run tests or checks automatically.
|
|
264
|
+
Explicit `test` and `check` operations read the existing map without rewriting it;
|
|
265
|
+
`verify`, `bundle`, and browser `run` do not refresh. Dry-run packaging/build
|
|
266
|
+
validates an existing map without rewriting it, and `import-map` itself has no
|
|
267
|
+
supported dry-run.
|
|
268
|
+
|
|
269
|
+
Generation stages the artifact and every selected HTML document beside their
|
|
270
|
+
destinations and uses backups to restore the prior managed files after a
|
|
271
|
+
handled pre-commit failure. Success reports `committed: true` and the complete
|
|
272
|
+
managed path inventory. Cleanup failures after commit remain warnings. This is
|
|
273
|
+
a handled-error transaction, not a claim of one filesystem-atomic rename for
|
|
274
|
+
all files and not a durable crash journal.
|
|
275
|
+
|
|
276
|
+
When tests are explicitly selected, external app tests receive an
|
|
277
|
+
`arcane-test-import-map/1` context for that app's managed map. Each isolated
|
|
278
|
+
Node child uses the existing loader for managed names and URL-like compatibility
|
|
279
|
+
keys. Materialized
|
|
280
|
+
modules such as `arcane/TimeGuard` and `arcane/DBOPFS` resolve their canonical
|
|
281
|
+
`arcane-os/event-manager` self-import through this managed map; raw Node import
|
|
282
|
+
of projected `arcane/**` files is not a separate public resolution contract.
|
|
283
|
+
Unmapped `arcane/*` and `#arcane/*` names fail
|
|
284
|
+
`ARCANE_IMPORT_MAP_UNRESOLVED`; ordinary Node exports and test runs without an
|
|
285
|
+
app context retain their existing resolution.
|
|
286
|
+
|
|
287
|
+
No app watches, polls, downloads, or self-updates this map. An active operation's
|
|
288
|
+
heartbeat is event telemetry only and never regenerates browser state.
|
|
289
|
+
|
|
290
|
+
</details>
|
|
291
|
+
|
|
292
|
+
## Portable AI provider runtime
|
|
293
|
+
|
|
294
|
+
Application code should select a normalized role, not an internal protocol.
|
|
295
|
+
The exported
|
|
296
|
+
[`getAIProviderRuntime()` singleton](runtime-modules.md#aiproviderruntimejs)
|
|
297
|
+
comes from the selected runtime and owns independent `llm`, `stt`, and
|
|
298
|
+
`tts` selections. This SDK release ships browser-WASM LLM and browser
|
|
299
|
+
speech provider/2 adapters and also adapts selected TWiN Cloud LLM,
|
|
300
|
+
Core-backed Ollama LLM, on-device Whisper STT, and on-device Kokoro TTS routes
|
|
301
|
+
into provider/2. There is no cloud speech route;
|
|
302
|
+
other native, Core, or cloud routes require an externally supplied compatible
|
|
303
|
+
adapter. The singleton itself is not an authentication or capability token. It
|
|
304
|
+
normalizes inspection, model authority,
|
|
305
|
+
load/unload/dispose, cancellation, stream cleanup, status, and startup
|
|
306
|
+
barriers. Each selected provider retains its real execution requirements.
|
|
307
|
+
`localOnly` creates no fallback, and failure in one role never authorizes a Core,
|
|
308
|
+
cloud, or different-provider fallback.
|
|
309
|
+
|
|
310
|
+
For a browser-only LLM,
|
|
311
|
+
[`arcane-os/ai/browser-wasm`](ai/browser-wasm.md) exposes `createArcaneAI()`
|
|
312
|
+
and an adapter into the same provider-neutral lifecycle. For browser speech,
|
|
313
|
+
[`arcane-os/ai/browser-speech`](ai/browser-speech.md) creates independent
|
|
314
|
+
Whisper STT and Kokoro TTS providers that register directly with the normalized
|
|
315
|
+
runtime. The SDK supplies mechanism; applications retain model/runtime choice,
|
|
316
|
+
licenses, prompts, tools, voices, and disclosure policy.
|
|
317
|
+
|
|
318
|
+
### Browser-WASM LLM lifecycle
|
|
319
|
+
|
|
320
|
+
The shipped browser runtime contains the Wllama JavaScript/WASM engine and its
|
|
321
|
+
provider/cache/controller mechanism. It contains no model
|
|
322
|
+
weights, default model catalog, CDN fallback, native provider, speech model, or
|
|
323
|
+
application profile. The caller supplies each model as a source with
|
|
324
|
+
a nonempty ordered file list, so monolithic and split GGUF models use the same
|
|
325
|
+
contract. HTTPS redirects are followed and the final HTTPS URL is recorded.
|
|
326
|
+
Each member may optionally declare positive `bytes` for progress reporting and
|
|
327
|
+
HTTP Range planning. Declared and observed byte measures remain transfer-local
|
|
328
|
+
telemetry; they never validate, admit, identify, hash, or decide cache reuse for
|
|
329
|
+
model content.
|
|
330
|
+
|
|
331
|
+
On load, the DBOPFS store preserves descriptor order while one bounded worker
|
|
332
|
+
pool fetches split members or ranges within the selected member. A split member
|
|
333
|
+
may use one Range worker, allowing an interrupted shard to resume without
|
|
334
|
+
multiplying the configured concurrency. Download progress
|
|
335
|
+
retains its existing completed-file fields and adds raw aggregate bytes,
|
|
336
|
+
remaining bytes, rolling bytes per second, ETA seconds, active transfer
|
|
337
|
+
workers, the transfer limit, and the active transfer mode. Chunk-driven changes
|
|
338
|
+
are coalesced on a 250 ms cadence; start, plan/total, active-worker, and
|
|
339
|
+
completion boundaries may publish immediately. A source member that receives a redirected `200` probes the final URL
|
|
340
|
+
directly before reusing the original response as its single-fetch fallback.
|
|
341
|
+
Confirmed support uses deterministic OPFS Range parts of roughly 4 MB each, up
|
|
342
|
+
to 4,096 parts per member, with bounded active workers; completed parts and
|
|
343
|
+
split-model members survive interruption so a retry fetches only missing work.
|
|
344
|
+
Only unfinished active parts restart after refresh. Without usable range support
|
|
345
|
+
or an observable or declared total it falls back to one full fetch. A normal
|
|
346
|
+
cache miss may fetch only the
|
|
347
|
+
caller-supplied HTTPS sources; `offline:true` performs no model request and uses
|
|
348
|
+
only a compatible completed cache, otherwise it rejects with
|
|
349
|
+
`ARCANE_AI_MODEL_OFFLINE_MISS`. Unload releases the active Wllama session but
|
|
350
|
+
does not silently delete the app-owned cache. A complete whole member supersedes
|
|
351
|
+
its current resumable fragments. Cleanup failure is warned without hiding the
|
|
352
|
+
usable model.
|
|
353
|
+
|
|
354
|
+
SDK `0.5.11` requires WebGPU. Load requests full offload and waits for the runtime
|
|
355
|
+
to report a loaded model. `navigator.gpu` presence alone is
|
|
356
|
+
not readiness. There is no CPU fallback, partial-offload success mode, or
|
|
357
|
+
silent switch to native/Core/cloud inference.
|
|
358
|
+
|
|
359
|
+
### Browser speech lifecycle
|
|
360
|
+
|
|
361
|
+
The browser-speech package contains plain-JavaScript authority, DBOPFS store,
|
|
362
|
+
provider, client, and Worker machinery. It redistributes no Whisper, Kokoro,
|
|
363
|
+
ONNX, model, voice, third-party license, or corresponding-source payload.
|
|
364
|
+
Default upstream integrations use `createBrowserSpeechAuthority()` with a
|
|
365
|
+
version-pinned npm/package runtime entry and optional upstream `wasmPaths`;
|
|
366
|
+
the selected runtime then downloads models and voices through its normal
|
|
367
|
+
provider fetch and browser cache behavior after explicit `load()`.
|
|
368
|
+
|
|
369
|
+
`createBrowserSpeechArtifactGraph()` is an ordinary materialization descriptor.
|
|
370
|
+
Browser speech uses the caller-selected upstream runtime, model, voice, Fetch,
|
|
371
|
+
cache, and Worker behavior.
|
|
372
|
+
|
|
373
|
+
Ordinary module routing preserves bare import specifiers for native import-map
|
|
374
|
+
resolution and leaves bare `fetch`, `caches`, and `Worker` calls unchanged when
|
|
375
|
+
the module declares a shadowing binding with the same name. Explicit
|
|
376
|
+
`globalThis` or `self` calls continue through the materialized-file router.
|
|
377
|
+
|
|
378
|
+
The speech Worker uses its ordinary global Worker message boundary directly for
|
|
379
|
+
requests, results, errors, and cancellation. It creates no private
|
|
380
|
+
`MessageChannel` and publishes no Worker progress transport.
|
|
381
|
+
|
|
382
|
+
Worker operations use `arcane-ai-speech-worker/1`. The public Worker client
|
|
383
|
+
supports `load`, `use`, `status`, `unload`, and `dispose`; the transport host
|
|
384
|
+
additionally supports its internal `cancel` control. Every other operation
|
|
385
|
+
rejects with code `ARCANE_AI_INVALID_REQUEST`, message
|
|
386
|
+
`The speech worker operation is not part of its protocol.`, and role-specific
|
|
387
|
+
reason `stt-worker-operation-unknown` or `tts-worker-operation-unknown`.
|
|
388
|
+
Failures use the separate
|
|
389
|
+
`arcane-ai-speech-worker-error/1` envelope. Its cause-free form has the four data
|
|
390
|
+
properties `code,message,protocol,reason`; the diagnostic form may add one `cause`
|
|
391
|
+
data property containing the complete serialized diagnostic, including cycles.
|
|
392
|
+
The protocol, registered code, nonempty message, reason, role, and operation
|
|
393
|
+
must agree. A foreign, incomplete, extra-keyed, accessor-bearing, cross-role,
|
|
394
|
+
or cross-operation error envelope is rejected and terminates that role Worker.
|
|
395
|
+
Nested module Workers use
|
|
396
|
+
`arcane-ai-browser-speech-artifact-module-worker/1` and report bootstrap
|
|
397
|
+
rejection only as `artifact-module-worker-bootstrap-rejected`.
|
|
398
|
+
|
|
399
|
+
If the platform cannot clone an exotic `cause`, the Worker keeps the complete
|
|
400
|
+
raw failure in its console diagnostics and retries settlement with the
|
|
401
|
+
cause-free four-field envelope. Nested Workers are terminated during role teardown.
|
|
402
|
+
|
|
403
|
+
Kokoro receives the exact selected `webgpu` or `wasm` device through
|
|
404
|
+
`KokoroTTS.from_pretrained()` and retains the caller-selected dtype. Its WASM
|
|
405
|
+
path is configured through `namespace.env.wasmPaths`; Transformers is configured
|
|
406
|
+
through `namespace.env.backends.onnx.wasm.wasmPaths`. Ordinary mode may use a
|
|
407
|
+
caller-selected version-pinned upstream directory and preserves the runtime's
|
|
408
|
+
browser cache. Optional `numThreads` is caller-owned and
|
|
409
|
+
Transformers-STT-only; a Kokoro declaration rejects with
|
|
410
|
+
`ARCANE_AI_KOKORO_ENV_NUM_THREADS_FIELD_NOT_EXPOSED` /
|
|
411
|
+
`kokoro-env-num-threads-field-not-exposed`. Missing or rejected namespace
|
|
412
|
+
shapes report distinct `*-unavailable` and
|
|
413
|
+
`*-assignment-rejected` reasons for each setting; the Worker never
|
|
414
|
+
substitutes a different namespace. The caller also owns dtype, STT input sample
|
|
415
|
+
rate, TTS output sample rate, default voice, and the complete voice inventory.
|
|
416
|
+
Kokoro execution defaults to `{device:'auto',maxConcurrentRequests:4}` and may
|
|
417
|
+
be overridden with `webgpu` or `wasm` and an integer capacity from 1 through 4.
|
|
418
|
+
Automatic selection attempts a complete WebGPU pool only when WebGPU is exposed,
|
|
419
|
+
then tears it down and forms a complete WASM pool if WebGPU loading rejects. It
|
|
420
|
+
does not change the selected runtime, model, dtype, or voice.
|
|
421
|
+
|
|
422
|
+
Each capacity slot owns one Worker/model session. The provider-neutral runtime
|
|
423
|
+
admits the first four requests and retains segment 5 and later in its FIFO
|
|
424
|
+
queue without dropping content. Synthesis may finish out of order; high-level
|
|
425
|
+
AI playback waits for earlier segments and schedules the contiguous ready
|
|
426
|
+
prefix in exact input order. More sessions trade memory for latency, without
|
|
427
|
+
promising physical GPU kernel overlap.
|
|
428
|
+
|
|
429
|
+
Applications using `AI.configureBrowserSpeech()` can read
|
|
430
|
+
`ai.providerRuntime.status('tts', {execution:true}).execution` instead of
|
|
431
|
+
reaching into provider internals. The optional provider snapshot exposes
|
|
432
|
+
Kokoro's `requestedDevice`, `selectedDevice`, `maxConcurrentRequests`, and
|
|
433
|
+
`activeRequestCount`. The default `status()` retains its original sticky-state
|
|
434
|
+
behavior; explicit execution inspection does not load a provider or emit a
|
|
435
|
+
state event. See [browser speech](ai/browser-speech.md) for complete examples.
|
|
436
|
+
|
|
437
|
+
The SDK is not the distributor of the selected upstream speech packages or
|
|
438
|
+
provider assets and does not republish their legal/source payloads. Package,
|
|
439
|
+
model, voice, and version selection belongs to each consuming application, not
|
|
440
|
+
to a shared SDK component ledger or execution/publication gate.
|
|
441
|
+
|
|
442
|
+
Whisper `stt` and Kokoro `tts` each own catalog, inspect, status, load, request,
|
|
443
|
+
unload, and dispose state. They load, cancel, unload, fail, and recover
|
|
444
|
+
independently from the LLM and from one another. Whisper owns one Worker and one
|
|
445
|
+
request. Kokoro owns a bounded pool of distinct Workers and loaded model
|
|
446
|
+
sessions because the selected browser adapter serializes inference inside one
|
|
447
|
+
JavaScript isolate. Pool loading first completes one model session, then loads
|
|
448
|
+
the remaining Worker sessions concurrently against the same prepared artifact
|
|
449
|
+
selection. One Kokoro request cancellation suppresses only that result and
|
|
450
|
+
sends the targeted Worker cancel control; upstream may still finish work
|
|
451
|
+
already inside `generate()`. Kokoro unload terminates the whole pool. Whisper
|
|
452
|
+
cancellation after Worker use begins retains destructive Worker teardown. If
|
|
453
|
+
shared STT `Blob` decoding is cancelled before Worker use, the request rejects
|
|
454
|
+
while the loaded provider remains ready.
|
|
455
|
+
Speech failure neither disables text chat nor retries through another local,
|
|
456
|
+
native, or cloud provider. The provider/Worker layer is event-neutral: it
|
|
457
|
+
exposes promises, `AbortSignal`, and precise lifecycle/status records, but owns
|
|
458
|
+
no event bus or listener registry. The provider/2 load context accepts an
|
|
459
|
+
optional progress callback for interface compatibility; the current
|
|
460
|
+
browser-speech artifact and Worker transport publishes no progress records.
|
|
461
|
+
|
|
462
|
+
### Persistent chat and document context
|
|
463
|
+
|
|
464
|
+
The SDK runtime owns
|
|
465
|
+
[`DBOPFSDocumentLibrary`](runtime-modules.md#dbopfsdocumentlibraryjs),
|
|
466
|
+
[`DocumentLexicalSearch`](runtime-modules.md#documentlexicalsearchjs), and
|
|
467
|
+
[`PersistentAIChatSession`](runtime-modules.md#persistentaichatsessionjs).
|
|
468
|
+
DBOPFS JSONL parsing preserves every nonblank unreadable row as its original
|
|
469
|
+
string. Persistent chat can therefore expose the complete saved transcript for
|
|
470
|
+
application-owned inspection and recovery while rejecting that row from
|
|
471
|
+
provider-facing history with a coded persistence error.
|
|
472
|
+
Document bootstrap is explicit and schema-driven, commits a completed
|
|
473
|
+
generation last, and returns complete search results with partial read failures
|
|
474
|
+
disclosed. `evaluate()` can instead score a caller-owned source set without
|
|
475
|
+
persisting its bodies.
|
|
476
|
+
A chat session never searches the corpus unless the application
|
|
477
|
+
deliberately wires a document context builder into the request; generated
|
|
478
|
+
document context remains labeled untrusted.
|
|
479
|
+
|
|
480
|
+
Persistent chat maintains recurring model context plus a sanitized `ChatEntity`
|
|
481
|
+
transcript according to the caller's persistence choice. Structural calls, IDs,
|
|
482
|
+
argument envelopes, and raw results exist only through the one active provider
|
|
483
|
+
continuation that requires them. When that continuation settles, recurring
|
|
484
|
+
model context replaces the protocol exchange with its complete user-facing call
|
|
485
|
+
messages, any supplied public result messages, and the model's visible response.
|
|
486
|
+
Reasoning, request metadata, raw protocol, and raw tool returns do not recur.
|
|
487
|
+
Durable user and assistant turns retain only role, complete visible content, and
|
|
488
|
+
timestamp.
|
|
489
|
+
Durable tool turns retain only role, the required user-facing message as
|
|
490
|
+
content, and optional public name and result status. System prompts remain in
|
|
491
|
+
the live session only. Existing stored files are not rewritten on load. A turn
|
|
492
|
+
with `persist:false` participates in its one request and response only, then
|
|
493
|
+
remains absent from subsequent model context, the retained transcript, memory
|
|
494
|
+
extraction, and DBOPFS.
|
|
495
|
+
|
|
496
|
+
For an automatic model-authored conversation opening, the application calls the
|
|
497
|
+
persistent session's `open()` operation with its internal bootstrap message.
|
|
498
|
+
That bootstrap participates in the one provider request only. The operation
|
|
499
|
+
durably appends only the complete nonblank assistant response, so the opening
|
|
500
|
+
survives reload without a fabricated or retained user turn. A system prompt by
|
|
501
|
+
itself is not a retained conversation turn; an existing retained user,
|
|
502
|
+
assistant, or tool sequence prevents another opening.
|
|
503
|
+
|
|
504
|
+
### Cancellation and structural tools
|
|
505
|
+
|
|
506
|
+
Cancellation is part of the provider lifecycle, not just a UI decision.
|
|
507
|
+
`AbortSignal`, the normalized role cancel operation, and stream-handle
|
|
508
|
+
`cancel(reason)` propagate to the selected provider. Browser-WASM inference
|
|
509
|
+
requires positive llama cancellation acknowledgement when cancellation is
|
|
510
|
+
required. Browser Whisper cancellation terminates its Worker after Worker use
|
|
511
|
+
begins. Browser Kokoro uses request-targeted cancellation so one synthesis does
|
|
512
|
+
not terminate sibling pool slots; delivery suppression is immediate, while
|
|
513
|
+
engine preemption remains upstream-cooperative. Cancellation during shared
|
|
514
|
+
browser decoding leaves the loaded Worker ready. Unload always cancels every
|
|
515
|
+
active role request before releasing that role's execution state, and
|
|
516
|
+
superseded late results are rejected rather than committed or retried through
|
|
517
|
+
another provider.
|
|
518
|
+
|
|
519
|
+
Interactive requests enter a FIFO lane independently for each role. Provider
|
|
520
|
+
capacity defaults to 1. A TTS provider may declare a positive safe-integer
|
|
521
|
+
`maxConcurrentRequests`; the runtime admits that many oldest requests and queues
|
|
522
|
+
overflow without discarding content. LLM and STT remain capacity 1. A caller
|
|
523
|
+
signal cancels only its own queued or active request, while explicit role
|
|
524
|
+
cancellation targets the oldest active request. Request-specific ownership
|
|
525
|
+
prevents canceled or superseded callbacks from clearing or restoring sibling
|
|
526
|
+
state. The runtime revalidates selected-provider readiness and never reloads,
|
|
527
|
+
switches, or falls back implicitly. Generic provider-promise settlement is not
|
|
528
|
+
a claim that underlying work stopped; only a provider's documented positive
|
|
529
|
+
acknowledgement or destructive worker teardown can prove that stronger fact.
|
|
530
|
+
|
|
531
|
+
`startAIRuntime({startLanguageModel:false,startTranscription:false})` is the
|
|
532
|
+
explicit startup boundary for browser-WASM LLM and default STT activation. It
|
|
533
|
+
leaves the selected LLM unloaded until the shared chat control publishes an
|
|
534
|
+
explicit user load intent; the
|
|
535
|
+
startup barrier then reports `chatReady:false` and `roles.llm.requested:false`
|
|
536
|
+
instead of beginning a browser-WASM download. The omitted/default
|
|
537
|
+
`startLanguageModel:true` preserves existing provider startup behavior. The
|
|
538
|
+
default `startTranscription:false` also declines to request a startup STT load
|
|
539
|
+
and does not unload a role already started through another
|
|
540
|
+
explicit lifecycle action. A selected unloaded
|
|
541
|
+
transcription provider remains selected and unloaded until a user lifecycle
|
|
542
|
+
intent or explicit `startTranscription:true` opt-in asks the provider owner to
|
|
543
|
+
load it. Neither state observation nor either shared speech component imports a
|
|
544
|
+
model or selects a fallback. `speech.html` and `voice-transcription.html` consume
|
|
545
|
+
one shared `createSTTActivationController()` contract for selected, unloaded,
|
|
546
|
+
loading, unloading, error, and ready presentation plus cancelable user intent.
|
|
547
|
+
Both keep capture unavailable until sticky STT state is exactly ready.
|
|
548
|
+
|
|
549
|
+
Each shared speech component owns an `AbortController` for its STT request and
|
|
550
|
+
passes its signal through `AI.fetchSTT()`. `voice-transcription.html` also adds
|
|
551
|
+
that signal to the existing injected `transcribe(file,context)` callback
|
|
552
|
+
context. Cancel, readiness loss, superseding capture, and component teardown
|
|
553
|
+
abort the owned signal and suppress late delivery. Whether the provider's
|
|
554
|
+
underlying computation stops remains governed by its own cancellation contract.
|
|
555
|
+
User TTS unmute calls `AI.setSpeechMuted(false)` before
|
|
556
|
+
or with its load intent so the runtime records the unmuted lifecycle preference;
|
|
557
|
+
an `initialMuted:false` component configuration preserves that intent across an
|
|
558
|
+
unselected or loading TTS route and exposes unmuted state only after readiness;
|
|
559
|
+
mute calls `AI.setSpeechMuted(true)`, cancels active synthesis, and unloads TTS.
|
|
560
|
+
The selected local TTS model catalog owns `defaultVoice`. AI.js never forwards
|
|
561
|
+
a saved OpenAI-route voice to Core or browser Kokoro.
|
|
562
|
+
|
|
563
|
+
LLM tool calls are structural result data only. The SDK never executes a
|
|
564
|
+
handler. The application owns schema validation, authorization, side-effect
|
|
565
|
+
policy, dispatch, and the matching tool-result turn.
|
|
566
|
+
|
|
567
|
+
Ordinary streaming publishes complete nonstructural content and reasoning from
|
|
568
|
+
every provider choice in order. Complete provider chunks and terminal records
|
|
569
|
+
remain independently available through the data callbacks. Structural deltas
|
|
570
|
+
stay private until terminal validation; terminal-only calls are valid, while
|
|
571
|
+
any observed call must keep the same choice, order, identity, exact argument
|
|
572
|
+
string, and extension fields at settlement. Awaiting a terminal result before
|
|
573
|
+
iterating does not stall the private provider stream; projected chunks remain
|
|
574
|
+
available to the later consumer.
|
|
575
|
+
|
|
576
|
+
Every first-party function-tool declaration includes
|
|
577
|
+
`function.parameters.properties.message` as a required nonempty string, and
|
|
578
|
+
every emitted call includes that plain-language user-facing value in the JSON
|
|
579
|
+
encoded by `function.arguments.message`. The application uses `message` for the
|
|
580
|
+
call's progress, question, or next step; it does not treat raw tool envelopes,
|
|
581
|
+
arguments, internal sequencing state, or protocol failures as ordinary
|
|
582
|
+
transcript content. An explicitly selected developer inspection surface may
|
|
583
|
+
show the raw structure separately. This `message` does not replace domain
|
|
584
|
+
fields such as a closing report's `final_message`. One assistant response may
|
|
585
|
+
contain an ordered array of calls with unique IDs. Display does not settle any
|
|
586
|
+
call: one atomic result batch must provide exactly one matching nonblank
|
|
587
|
+
executed, declined, cancelled, or not-executed `role:'tool'` turn for every
|
|
588
|
+
pending ID before another user or provider turn.
|
|
589
|
+
|
|
590
|
+
<details>
|
|
591
|
+
<summary>Portable AI protocol disclosure</summary>
|
|
592
|
+
|
|
593
|
+
The normalized runtime protocol is `arcane-ai-runtime/2`; registered adapters
|
|
594
|
+
implement `arcane-ai-provider/2` and select a model before load. The
|
|
595
|
+
browser-WASM component protocol is `arcane-ai-browser-wasm/2`; its
|
|
596
|
+
direct controller adapter uses `arcane-ai-adapter/1`, and
|
|
597
|
+
`adaptV1LlmProvider()` projects that surface into the provider/2 LLM role.
|
|
598
|
+
Browser speech stores identify themselves as
|
|
599
|
+
`arcane-ai-browser-speech-artifacts/1`. Direct authorities use
|
|
600
|
+
`arcane-ai-model-authority/1`. Optional browser-speech graphs use
|
|
601
|
+
`arcane-ai-browser-speech-artifact-graph/1`, kind
|
|
602
|
+
`browser-speech-authenticated-artifact-graph`. Those identifiers describe
|
|
603
|
+
lifecycle contracts; none is by itself a capability grant.
|
|
604
|
+
|
|
605
|
+
These identifiers normalize lifecycle records. They do not erase provider
|
|
606
|
+
availability: browser providers still require their browser capabilities,
|
|
607
|
+
native providers still require an admitted host and Core method, and cloud
|
|
608
|
+
providers still require explicit selection, network policy, and credentials.
|
|
609
|
+
|
|
610
|
+
</details>
|
|
611
|
+
|
|
612
|
+
## Arcane application protocol
|
|
613
|
+
|
|
614
|
+
`globalThis.Arcane.protocol` is `arcane/1`. The shared API wraps transport
|
|
615
|
+
selection, request ids, JSON-safe values, promise settlement, `Arcane.Error`,
|
|
616
|
+
and renderer events. The current transport snapshot is synchronous:
|
|
617
|
+
|
|
618
|
+
```javascript
|
|
619
|
+
const {connected, transport, native, managedLocalAI} =
|
|
620
|
+
globalThis.Arcane.runtime.current();
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
Transport values are `webview2`, `webkitgtk`, `android-webview`,
|
|
624
|
+
`development-http`, and `standalone`. `connected` means a callable transport
|
|
625
|
+
was initialized. It does not prove that Core answered, the method is admitted,
|
|
626
|
+
or a dependency is ready.
|
|
627
|
+
|
|
628
|
+
## Native host transports
|
|
629
|
+
|
|
630
|
+
### Microsoft NT / WebView2
|
|
631
|
+
|
|
632
|
+
The renderer uses the WebView2 host messaging surface. The host binds one app
|
|
633
|
+
identity and native policy to the session before Core dispatch. Microsoft NT
|
|
634
|
+
can expose managed-service and privileged platform operations that do not exist
|
|
635
|
+
in an ordinary browser.
|
|
636
|
+
|
|
637
|
+
### Linux / WebKitGTK
|
|
638
|
+
|
|
639
|
+
The renderer uses the WebKitGTK host bridge with the same application-facing
|
|
640
|
+
`Arcane` protocol. Linux can implement the same normalized methods through
|
|
641
|
+
different host code. Some administrator-owned service settings intentionally
|
|
642
|
+
return unsupported/manual guidance rather than imitating Microsoft NT mutation.
|
|
643
|
+
|
|
644
|
+
### Android / Android WebView
|
|
645
|
+
|
|
646
|
+
Android injects a main-frame, origin-bound bridge for the packaged application.
|
|
647
|
+
Its generated registry binds application identity, package version, entry,
|
|
648
|
+
grants, and method policy. Android exposes a narrower surface, including an
|
|
649
|
+
admitted user-managed local-AI chat projection where configured. Desktop model
|
|
650
|
+
management is not projected merely because a user-managed Ollama listener is
|
|
651
|
+
reachable.
|
|
652
|
+
|
|
653
|
+
### macOS
|
|
654
|
+
|
|
655
|
+
No macOS target, native bridge, Core host, artifact, or run contract is exposed
|
|
656
|
+
by this SDK version. A browser may still run browser-only application code, but
|
|
657
|
+
that does not create a native Arcane host or satisfy a native capability.
|
|
658
|
+
|
|
659
|
+
## Development and remote HTTP transport
|
|
660
|
+
|
|
661
|
+
The development HTTP bridge makes the same application-facing request shape
|
|
662
|
+
available without pretending the browser is a native host. It is a development
|
|
663
|
+
transport, not a production isolation or authority boundary. A remotely
|
|
664
|
+
operated client can use an expressly configured web transport only when the
|
|
665
|
+
host, origin, application identity, and policy admit it; Arcane does not silently
|
|
666
|
+
swap native calls to arbitrary remote HTTP endpoints.
|
|
667
|
+
|
|
668
|
+
When transport changes while the public method remains the same, request
|
|
669
|
+
settlement and public errors stay normalized. Host-specific availability and
|
|
670
|
+
result detail remain documented by the method.
|
|
671
|
+
|
|
672
|
+
## Core dispatch and capability admission
|
|
673
|
+
|
|
674
|
+
The host binds the caller's application identity. Core checks the exact method,
|
|
675
|
+
required capability, allowed application type/id, privilege, mutation
|
|
676
|
+
exclusivity, request bounds, and relevant package policy. Renderer-supplied app
|
|
677
|
+
ids or grants never replace that bound identity.
|
|
678
|
+
|
|
679
|
+
`Arcane.capabilities.list()` is the Core-side application preflight. It reports
|
|
680
|
+
current grants and admitted methods but does not reserve authority for a later
|
|
681
|
+
call. Each call is checked again.
|
|
682
|
+
|
|
683
|
+
## Arcane Ollama protocol path
|
|
684
|
+
|
|
685
|
+
The safe application path is:
|
|
686
|
+
|
|
687
|
+
```text
|
|
688
|
+
renderer Ollama.js or Arcane.ollama
|
|
689
|
+
-> arcane/1 host request
|
|
690
|
+
-> Core capability and package-policy admission
|
|
691
|
+
-> managed ArcaneOllama loopback service
|
|
692
|
+
-> complete Ollama HTTP operation
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
Applications never connect directly to `localhost:11434`. Core owns loopback
|
|
696
|
+
endpoint selection, method policy, stream ids,
|
|
697
|
+
chunk events, model-policy checks, native resource admission, and managed
|
|
698
|
+
mutation workflows.
|
|
699
|
+
|
|
700
|
+
Direct Ollama methods preserve the complete provider-native success envelope.
|
|
701
|
+
Arcane normalizes the outer promise/error and stream lifecycle. `chatText`,
|
|
702
|
+
`generateText`, and `readiness` are helper-level normalizers.
|
|
703
|
+
|
|
704
|
+
## Explicit cloud provider path
|
|
705
|
+
|
|
706
|
+
`arcane/AI` can use an explicitly selected and configured cloud
|
|
707
|
+
profile over HTTPS. That path is not Core transport fallback. The module adapts
|
|
708
|
+
the selected provider into its high-level application behavior, while provider
|
|
709
|
+
diagnostics and optional fields can remain provider-specific. Native policy and
|
|
710
|
+
network policy still govern a native renderer's outbound access.
|
|
711
|
+
|
|
712
|
+
Local failure never authorizes cloud disclosure. The user or owning application
|
|
713
|
+
must select and configure the cloud provider explicitly.
|
|
714
|
+
|
|
715
|
+
## Events, streaming, and cancellation
|
|
716
|
+
|
|
717
|
+
Renderer-visible Core events are listed in
|
|
718
|
+
[the Arcane event reference](core/arcane-events.md). Durable
|
|
719
|
+
`transport.ready` and `core.ready` completions can be observed after the fact
|
|
720
|
+
with `Arcane.events.when()`. Ordinary progress, stream, terminal, and appearance
|
|
721
|
+
events are future-only.
|
|
722
|
+
|
|
723
|
+
Ollama streaming correlates chunks to the originating request. A renderer
|
|
724
|
+
abort or timeout can stop observation without proving that a non-cooperative
|
|
725
|
+
host mutation stopped. Method guides state whether Core cooperatively cancels,
|
|
726
|
+
whether partial provider state can remain, and which status call must be
|
|
727
|
+
refreshed before retry.
|
|
728
|
+
|
|
729
|
+
## Cross-kernel normalization boundary
|
|
730
|
+
|
|
731
|
+
The common contract ends where platform truth must remain different:
|
|
732
|
+
|
|
733
|
+
- API names, promise/error behavior, host capability policy, and public
|
|
734
|
+
operation events are normalized;
|
|
735
|
+
- host availability, privilege model, installation/service mechanism, native
|
|
736
|
+
artifact kind, and some diagnostic/result fields remain platform-specific;
|
|
737
|
+
- unsupported platforms fail or return a documented unsupported state; they do
|
|
738
|
+
not run an unrelated browser implementation as a substitute;
|
|
739
|
+
- this SDK version requires a selected checkout and Core to provide the current
|
|
740
|
+
native plan's protocol, version, feature, capability, method, and provider;
|
|
741
|
+
- that current-build compatibility does not promise that a future SDK will accept
|
|
742
|
+
this Core or that this SDK will accept a future Core.
|
|
743
|
+
|
|
744
|
+
## Complete-content boundary
|
|
745
|
+
|
|
746
|
+
SDK runtime, app releases, import-map files, bundles, native plans, providers,
|
|
747
|
+
and artifacts preserve their complete selected content. Required credential
|
|
748
|
+
protection, genuinely malformed input rejection, applicable law, external
|
|
749
|
+
protocol requirements, and host platform safety remain in effect.
|