arcane-os 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +8 -8
- package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +29 -22
- package/browser-runtime/ai/ARCANE_AI_BROWSER_SPEECH_COMPONENTS.json +203 -0
- package/browser-runtime/ai/browser-kokoro-worker.mjs +11 -2
- package/browser-runtime/ai/browser-speech-artifacts.mjs +3230 -397
- package/browser-runtime/ai/browser-speech-providers.mjs +1141 -157
- package/browser-runtime/ai/browser-speech.mjs +2 -0
- package/browser-runtime/ai/browser-whisper-worker.mjs +11 -2
- package/browser-runtime/ai/model-controller.mjs +285 -95
- package/browser-runtime/ai/speech-worker-client.mjs +247 -32
- package/browser-runtime/ai/speech-worker-runtime.mjs +2310 -167
- package/browser-runtime/event-manager.mjs +1097 -1
- package/docs/architecture.md +2 -2
- package/docs/event-manager.md +155 -27
- package/docs/reference/README.md +27 -27
- package/docs/reference/ai/browser-speech-package-authority.json +835 -0
- package/docs/reference/ai/browser-speech.md +1162 -246
- package/docs/reference/ai/browser-wasm.md +18 -7
- package/docs/reference/availability-and-normalization.md +6 -3
- package/docs/reference/behavioral-testing.md +29 -6
- package/docs/reference/cli.md +117 -9
- package/docs/reference/core/arcane-ai-contracts.md +1 -1
- package/docs/reference/event-manager.md +577 -32
- package/docs/reference/inventory/package-api.json +478 -2
- package/docs/reference/inventory/runtime-components.json +108 -44
- package/docs/reference/inventory/runtime-modules.json +131 -53
- package/docs/reference/mail.md +316 -0
- package/docs/reference/protocols.md +157 -43
- package/docs/reference/runtime-components.md +258 -83
- package/docs/reference/runtime-modules.md +613 -77
- package/docs/reference/sdk-api.md +1014 -25
- package/package.json +5 -4
- package/runtime/ARCANE_RUNTIME_RELEASE.json +145 -140
- package/runtime/arcane/components/app-bar.html +34 -13
- package/runtime/arcane/components/assistant-panel.html +110 -57
- package/runtime/arcane/components/calculator.html +7 -4
- package/runtime/arcane/components/chart.html +58 -17
- package/runtime/arcane/components/chat.html +606 -136
- package/runtime/arcane/components/conversation-view.html +13 -6
- package/runtime/arcane/components/dashboard-config.html +96 -59
- package/runtime/arcane/components/data-maintenance.html +69 -14
- package/runtime/arcane/components/data-view.html +53 -7
- package/runtime/arcane/components/directory-picker.html +118 -32
- package/runtime/arcane/components/document-inspector.html +47 -10
- package/runtime/arcane/components/file-drop.html +81 -35
- package/runtime/arcane/components/file-inspector.html +72 -22
- package/runtime/arcane/components/file-manager.html +374 -79
- package/runtime/arcane/components/integration-settings.html +12 -5
- package/runtime/arcane/components/local-ai-status.html +48 -19
- package/runtime/arcane/components/markdown-document.html +161 -68
- package/runtime/arcane/components/markdown-editor.html +110 -33
- package/runtime/arcane/components/media-embed.html +8 -5
- package/runtime/arcane/components/modal.html +15 -5
- package/runtime/arcane/components/output-panel.html +28 -23
- package/runtime/arcane/components/preferences-form.html +22 -4
- package/runtime/arcane/components/record-timeline.html +18 -2
- package/runtime/arcane/components/relationship-board.html +23 -3
- package/runtime/arcane/components/screen-capture.html +10 -4
- package/runtime/arcane/components/source-code-viewer.html +76 -9
- package/runtime/arcane/components/source-explanation.html +23 -3
- package/runtime/arcane/components/speech.html +462 -384
- package/runtime/arcane/components/summary-strip.html +22 -11
- package/runtime/arcane/components/table.html +39 -21
- package/runtime/arcane/components/task-progress.html +79 -21
- package/runtime/arcane/components/terminal-workspace.html +7 -4
- package/runtime/arcane/components/theme-editor.html +7 -3
- package/runtime/arcane/components/unified-inbox.html +9 -4
- package/runtime/arcane/components/voice-transcription.html +639 -98
- package/runtime/arcane/components/weather-widget.html +5 -3
- package/runtime/arcane/components/web-navigator.html +48 -8
- package/runtime/arcane/entities/Chat.js +1 -1
- package/runtime/arcane/entities/User.js +110 -23
- package/runtime/arcane/modules/AI.js +2109 -130
- package/runtime/arcane/modules/AIProviderRuntime.js +720 -13
- package/runtime/arcane/modules/AIRuntimeState.js +109 -52
- package/runtime/arcane/modules/ApiModelDatabase.js +390 -17
- package/runtime/arcane/modules/BrowserTestSuite.js +205 -28
- package/runtime/arcane/modules/CalculatorEngine.js +63 -3
- package/runtime/arcane/modules/CommunicationAppController.js +588 -28
- package/runtime/arcane/modules/CommunicationHub.js +590 -10
- package/runtime/arcane/modules/ComponentContracts.js +470 -0
- package/runtime/arcane/modules/ConversationTimebox.js +152 -33
- package/runtime/arcane/modules/DBLS.js +40 -7
- package/runtime/arcane/modules/DBOPFS.js +35 -11
- package/runtime/arcane/modules/DataMaintenance.js +12 -2
- package/runtime/arcane/modules/Errors.js +65 -7
- package/runtime/arcane/modules/HTMLImport.js +198 -14
- package/runtime/arcane/modules/LocalAIReadinessController.js +208 -29
- package/runtime/arcane/modules/Mail.js +738 -115
- package/runtime/arcane/modules/MailOutbox.mjs +1395 -0
- package/runtime/arcane/modules/MailTransport.mjs +197 -39
- package/runtime/arcane/modules/Ollama.js +36 -1
- package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +583 -7
- package/runtime/arcane/modules/PreferenceStore.js +367 -33
- package/runtime/arcane/modules/RecordReviewStore.js +322 -23
- package/runtime/arcane/modules/ScreenCapture.js +1397 -15
- package/runtime/arcane/modules/SpeechPlayback.js +438 -41
- package/runtime/arcane/modules/TerminalClient.js +277 -12
- package/runtime/arcane/modules/ThemeBootstrap.js +80 -6
- package/runtime/arcane/modules/ThemeManager.js +39 -7
- package/runtime/arcane/modules/TimeGuard.js +131 -20
- package/runtime/arcane/modules/WaitForComponent.js +386 -33
- package/schemas/arcane-lock.schema.json +2 -2
- package/src/cli/main.mjs +435 -9
- package/src/event-manager.mjs +1097 -1
- package/src/import-map.mjs +21 -3
- package/src/index.mjs +13 -0
- package/src/installed-sdk-runtime.mjs +112 -0
- package/src/mail-api.mjs +22 -0
- package/src/mail-credentials.mjs +667 -0
- package/src/mail-server.mjs +1769 -0
- package/src/mail.mjs +261 -0
- package/src/sdk-browser-runtime.mjs +85 -41
- package/src/testing-loader.mjs +7 -0
- package/src/toolchain.mjs +3 -0
- package/src/workspace.mjs +1 -1
|
@@ -13,6 +13,29 @@ Apps import renderer ESM from `/arcane/modules/<file>`. Classic scripts, the OPF
|
|
|
13
13
|
- **Cloud** means the module can call an explicitly configured remote provider; it never implies automatic local-to-cloud fallback.
|
|
14
14
|
- **Node**, **worker**, and **vendor** identify specialized runtimes.
|
|
15
15
|
|
|
16
|
+
## Runtime semantic events and teardown
|
|
17
|
+
|
|
18
|
+
SDK runtime modules publish semantic state and lifecycle occurrences through the
|
|
19
|
+
one branded, versioned `globalThis.arcaneEvents` authority in each JavaScript
|
|
20
|
+
realm. A class can retain its existing `EventTarget` or `on()` compatibility
|
|
21
|
+
surface, but that surface delegates to a `createArcaneEventSource()` view scoped
|
|
22
|
+
by the module's source and instance identifiers; it does not own a second event
|
|
23
|
+
bus, listener `Map`, or listener `Set`. Every canonical occurrence and every
|
|
24
|
+
one-way DOM compatibility projection carries an occurrence ID. DOM input events
|
|
25
|
+
remain local UI/platform input, and projected DOM `CustomEvent`s must not be
|
|
26
|
+
mirrored back into the canonical source.
|
|
27
|
+
|
|
28
|
+
`arcaneEvents.subscribe(type,handler,{once,signal})` and source-scoped
|
|
29
|
+
`subscribe()`/`on()` registrations return one idempotent unsubscribe function
|
|
30
|
+
(also exposed as `.dispose`). The singleton's legacy `on()`/`once()` methods are
|
|
31
|
+
chainable compatibility APIs that return the manager; lifecycle-owned consumers
|
|
32
|
+
use `subscribe()`. Instance `dispose()`/`destroy()` methods remove owned
|
|
33
|
+
listeners, abort owned work, suppress stale settlement, and dispose the instance
|
|
34
|
+
source. Module-lifetime singleton sources instead expose a focused module
|
|
35
|
+
teardown function where teardown is supported. Event publication is synchronous
|
|
36
|
+
and observational; promises, `AbortSignal`, and `createEventQueue` continue to
|
|
37
|
+
own asynchronous work, cancellation, and backpressure.
|
|
38
|
+
|
|
16
39
|
## Canonical inventory
|
|
17
40
|
|
|
18
41
|
| Module | Kind | Capability | Availability | Normalization |
|
|
@@ -41,7 +64,7 @@ Apps import renderer ESM from `/arcane/modules/<file>`. Classic scripts, the OPF
|
|
|
41
64
|
| [`CommunicationHub.js`](#communicationhubjs) | esm | Fans out provider refresh/send operations and aggregates normalized threads/messages. | Cross-host with injected providers | Normalized aggregates; refresh contains per-provider failures. |
|
|
42
65
|
| [`CommunicationPreferences.js`](#communicationpreferencesjs) | esm | Stores app-scoped, non-secret communication provider preferences. | Browser / native WebView hybrid | Normalized preference record; storage failures mixed. |
|
|
43
66
|
| [`CommunicationProviderRegistry.js`](#communicationproviderregistryjs) | esm | Registers and queries validated provider definitions, channels, and required methods. | Cross-host | Strict normalized registry. |
|
|
44
|
-
| [`ComponentContracts.js`](#componentcontractsjs) | esm | Owns normalized configuration/value contracts shared
|
|
67
|
+
| [`ComponentContracts.js`](#componentcontractsjs) | esm | Owns normalized configuration/value contracts and shared explicit STT activation behavior for chart, dashboard, Markdown, and voice components. | Cross-host | Fully normalized labels, rows, definitions, visibility, formats, editor and voice options, plus capability-neutral STT activation intent and presentation state. |
|
|
45
68
|
| [`ConfiguredAIChatSession.js`](#configuredaichatsessionjs) | esm | Owns bounded in-memory AI turns, context construction, response-length instruction, and atomic history commit. | Native bridge by default; cross-host with injected chat | Normalized session/result; provider rejection preserved. |
|
|
46
69
|
| [`ConversationActionItems.js`](#conversationactionitemsjs) | esm | Normalizes, creates, updates, remembers, selects, and formats bounded conversation action items. | Cross-host | Fully normalized status/base/presentation contract. |
|
|
47
70
|
| [`ConversationClosingReport.js`](#conversationclosingreportjs) | esm | Defines the closing-report tool, instruction, result normalizer, call classifier, and formatter. | Cross-host | Fully normalized report contract. |
|
|
@@ -64,6 +87,7 @@ Apps import renderer ESM from `/arcane/modules/<file>`. Classic scripts, the OPF
|
|
|
64
87
|
| [`LocalAIReadiness.js`](#localaireadinessjs) | esm | Derives selected AI requirements and returns a frozen readiness/recovery report across browser, desktop, and Android modes. | Browser/native hybrid | Fully normalized report and stable error codes; browsers never probe Ollama. |
|
|
65
88
|
| [`LocalAIReadinessController.js`](#localaireadinesscontrollerjs) | esm | Coordinates local-AI status component checks, ensured recovery, availability projection, and teardown. | Browser/native hybrid | Normalized controller state and change events. |
|
|
66
89
|
| [`Mail.js`](#mailjs) | esm | Builds bounded reports and prefers the native mail capability with an explicit HTTP transport fallback. | Browser/native hybrid + cloud | Mail inputs/results normalized; transport failures mixed. |
|
|
90
|
+
| [`MailOutbox.mjs`](#mailoutboxmjs) | esm | Persists bounded mail reports before delivery and normalizes idempotent enqueue, retry, reconciliation, and invalid-record maintenance. | Browser/native WebView or compatible injected host | Frozen records, bounded work, cancellation, and lifecycle states normalized; storage, lock, and delivery failures coded. |
|
|
67
91
|
| [`MailTransport.mjs`](#mailtransportmjs) | esm | Sends one bounded mail report to a normalized HTTP(S) endpoint with timeout and response-size limits. | Browser/server with fetch + cloud | Normalized endpoint/timeout/size errors; remote detail bounded. |
|
|
68
92
|
| [`Marked.min.js`](#markedminjs) | esm | Vendored Marked 18.0.5 Markdown lexer, parser, renderer, extension, and walk-token API. | Cross-host vendor module | Vendor-native Marked contract. |
|
|
69
93
|
| [`MD.js`](#mdjs) | esm | Renders Markdown with Marked and exposes a DOM-sanitized projection. | Browser / native WebView | Raw Marked behavior plus Arcane sanitization; parse errors vendor-native. |
|
|
@@ -111,10 +135,13 @@ Provider-selectable chat, speech-to-text, text-to-speech, tool calling, structur
|
|
|
111
135
|
|
|
112
136
|
### Public surface
|
|
113
137
|
|
|
114
|
-
default `AI`; read-only `providerRuntime
|
|
115
|
-
`
|
|
138
|
+
default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and
|
|
139
|
+
`browserSpeechDescriptor`; `configureBrowserSpeech(configuration,{signal})`,
|
|
140
|
+
`disposeBrowserSpeech({signal})`, `setAI()`, `configureProviders()`,
|
|
141
|
+
`configureSpeechProviders()`, `transitionAI()`, `transitionProviders()`,
|
|
142
|
+
`transitionSpeechProviders()`, `startProviders()`, `setSpeechMuted()`,
|
|
116
143
|
`streamRequest()`, `streamMessage()`, `fetchRequest()`, `fetch()`,
|
|
117
|
-
`streamTTS()`, `finishTTS()`, `fetchSTT()`, `stopAudio()`, `resumeAudio()`,
|
|
144
|
+
`streamTTS()`, `finishTTS()`, `fetchTTS()`, `fetchSTT()`, `stopAudio()`, `resumeAudio()`,
|
|
118
145
|
`playAudio()`; consumes `user-entity-loaded` and `arcane-ollama-ready`,
|
|
119
146
|
installs `window.ai`, and emits `ai-ready`.
|
|
120
147
|
|
|
@@ -138,18 +165,200 @@ the exact selected provider/model catalog `defaultVoice`; a saved OpenAI voice
|
|
|
138
165
|
is used only by the selected OpenAI adapter and is never forwarded to another
|
|
139
166
|
provider route.
|
|
140
167
|
|
|
168
|
+
`configureSpeechProviders({stt,tts})` commits only the two speech routes and
|
|
169
|
+
leaves the current LLM route and sticky lifecycle record unchanged. Both speech
|
|
170
|
+
roles must be unloaded and own no request, load, unload, or dispose operation.
|
|
171
|
+
`transitionSpeechProviders({stt,tts})` stops queued audio, explicitly unloads
|
|
172
|
+
only STT and TTS, then commits that same closed speech route record. Neither
|
|
173
|
+
method loads a model, selects a fallback, or changes caller-owned model or voice
|
|
174
|
+
policy.
|
|
175
|
+
|
|
141
176
|
`startProviders({startMuted=true,startTranscription=false,signal=null}={})`
|
|
142
177
|
starts text chat without requesting an STT load by default; it does not undo an
|
|
143
|
-
already ready or independently loading
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
178
|
+
already ready or independently loading LLM or STT role. Its default
|
|
179
|
+
`startMuted:true` path cancels active TTS work and unloads TTS. Callers must opt
|
|
180
|
+
into eager STT startup with `startTranscription:true` or publish the explicit
|
|
181
|
+
user activation intent exposed by the shared speech component.
|
|
182
|
+
`setSpeechMuted(false)` records the public unmuted state only after the selected
|
|
183
|
+
TTS route reaches ready; a failed load leaves the public state muted. In contrast,
|
|
147
184
|
`setSpeechMuted(true)` cancels active TTS work and unloads that role.
|
|
185
|
+
`fetchTTS({model,voice,input,responseFormat,speed},signal)` accepts the public
|
|
186
|
+
provider-neutral synthesis shape, requires any explicit model to match the
|
|
187
|
+
admitted route, and admits an omitted voice only from the selected model
|
|
188
|
+
catalog's `defaultVoice`. An omitted response format preserves the instance's
|
|
189
|
+
existing `audioFormat` for a compatibility-only catalog. When the selected model
|
|
190
|
+
declares `speech.responseFormats`, that setting is used only when admitted; if
|
|
191
|
+
the setting is the legacy `opus` default and the model rejects it, the catalog's
|
|
192
|
+
`speech.defaultResponseFormat` is used, while any other unsupported setting is
|
|
193
|
+
rejected. It propagates the caller-owned signal and returns a playable `Blob`;
|
|
194
|
+
it does not independently choose a provider, cloud fallback, model, runtime, or
|
|
195
|
+
voice policy for the application. Existing `streamTTS()` and `finishTTS()` use
|
|
196
|
+
this same request boundary.
|
|
148
197
|
`fetchSTT(audioFile,responseHandler,signal)` propagates the caller-owned signal;
|
|
198
|
+
provider routes accept a `Blob` or `File` directly and leave media decoding,
|
|
199
|
+
PCM normalization, and WAV construction to the selected shared provider;
|
|
149
200
|
delivery suppression is guaranteed after abort, while underlying provider-stop
|
|
150
201
|
claims remain limited to that provider's cancellation contract.
|
|
151
202
|
|
|
152
|
-
|
|
203
|
+
#### Browser speech configuration
|
|
204
|
+
|
|
205
|
+
The caller constructs a frozen authority record for one or both roles and
|
|
206
|
+
retains ownership of it. This example configures both:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
import AI, {
|
|
210
|
+
AI_BROWSER_SPEECH_CONFIGURATION_PROTOCOL
|
|
211
|
+
} from '/arcane/modules/AI.js';
|
|
212
|
+
|
|
213
|
+
const speechConfiguration = Object.freeze({
|
|
214
|
+
protocol: AI_BROWSER_SPEECH_CONFIGURATION_PROTOCOL,
|
|
215
|
+
id: 'app-speech-authority',
|
|
216
|
+
dbopfs,
|
|
217
|
+
tableName: 'browser-speech-artifacts', // optional
|
|
218
|
+
stt: Object.freeze({
|
|
219
|
+
providerId: 'app-whisper',
|
|
220
|
+
graph: sttGraph,
|
|
221
|
+
security: Object.freeze({secure: true}),
|
|
222
|
+
offline: false
|
|
223
|
+
}),
|
|
224
|
+
tts: Object.freeze({
|
|
225
|
+
providerId: 'app-kokoro',
|
|
226
|
+
graph: ttsGraph,
|
|
227
|
+
security: Object.freeze({secure: true}),
|
|
228
|
+
offline: false
|
|
229
|
+
})
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const ai = new AI(/* existing application AI preferences */);
|
|
233
|
+
const descriptor = await ai.configureBrowserSpeech(
|
|
234
|
+
speechConfiguration,
|
|
235
|
+
{signal}
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// Configuration does not load either role. Activate only from an explicit UI.
|
|
239
|
+
await ai.providerRuntime.load('stt', {signal});
|
|
240
|
+
await ai.setSpeechMuted(false); // loads the selected TTS role, then unmutes
|
|
241
|
+
|
|
242
|
+
// Teardown unloads, unregisters, and disposes only this SDK-owned configuration.
|
|
243
|
+
await ai.disposeBrowserSpeech({signal});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The record must be a frozen plain data record with exactly
|
|
247
|
+
`{protocol,id,dbopfs,tableName?,stt?,tts?}` and at least one role. Each supplied
|
|
248
|
+
frozen role is exactly `{providerId,graph,security,offline}` or
|
|
249
|
+
`{providerId,model,runtime,security?,offline}`. The graph and direct authority
|
|
250
|
+
forms are mutually exclusive; `providerId` and `id` are trimmed 1-128 character
|
|
251
|
+
strings, `graph` is the role-matching frozen graph returned by the SDK browser
|
|
252
|
+
speech artifact API, graph `security` must explicitly select `secure:true`, and
|
|
253
|
+
`offline` is boolean. The direct form forwards its
|
|
254
|
+
caller-selected model, runtime, and optional security descriptors to the shared
|
|
255
|
+
provider. In warn-first mode it may use an empty `model.files` inventory and a
|
|
256
|
+
version-pinned upstream `runtime.wasmPaths`; secure graph mode remains the
|
|
257
|
+
closed, content-addressed path. The application chooses every artifact,
|
|
258
|
+
immutable graph or direct model/runtime authority, provider ID, offline policy,
|
|
259
|
+
sample rate, and TTS default voice. `configureBrowserSpeech()` imports the shared
|
|
260
|
+
browser-speech module, creates one DBOPFS store, constructs and registers the
|
|
261
|
+
supplied Whisper and/or Kokoro provider/2 instances, atomically replaces only
|
|
262
|
+
the supplied STT/TTS routes, and returns a frozen descriptor. An initial or
|
|
263
|
+
later call may supply only `stt` or only `tts`; the omitted external Cloud/Core
|
|
264
|
+
role remains unchanged and is not claimed as SDK browser-provider ownership.
|
|
265
|
+
A partial replacement of an existing browser-managed record retains the same
|
|
266
|
+
`dbopfs` and `tableName`, carries every omitted managed browser provider and
|
|
267
|
+
route unchanged, and unregisters and disposes only the replaced provider after
|
|
268
|
+
commit. Supplying both roles remains one atomic replacement. Applications do not register those
|
|
269
|
+
providers, decode `Blob`/`File` data into PCM, construct WAV, select Worker URLs,
|
|
270
|
+
or reproduce DBOPFS cache or artifact verification logic.
|
|
271
|
+
|
|
272
|
+
The returned descriptor is exactly `{protocol,configurationId,stt,tts}`; an
|
|
273
|
+
external, unmanaged role is `null`. A managed STT descriptor is
|
|
274
|
+
`{role:'stt',providerId,modelId,artifactGraphId?,offline}`; TTS adds
|
|
275
|
+
`defaultVoice`. `artifactGraphId` is present only for the graph form.
|
|
276
|
+
`browserSpeechConfiguration` returns the exact caller-owned record when no
|
|
277
|
+
managed role is carried. After a partial replacement that carries another
|
|
278
|
+
managed role, it returns a frozen merged record with the replacement call's
|
|
279
|
+
`id` and the carried role's unchanged authority. It is non-null only while the
|
|
280
|
+
SDK still owns every represented browser provider and route;
|
|
281
|
+
`browserSpeechDescriptor` returns that descriptor on the same condition.
|
|
282
|
+
Configuration never loads a role, auto-downloads, selects an alternative
|
|
283
|
+
provider/model/runtime/voice, or falls back to cloud/browser speech.
|
|
284
|
+
|
|
285
|
+
Calling `configureBrowserSpeech()` again with the same active record for every
|
|
286
|
+
supplied role is an idempotent descriptor read. A different call is serialized,
|
|
287
|
+
aborts the prior owned operation, unloads only the replaced speech roles, atomically
|
|
288
|
+
replaces provider ownership/routes, and suppresses stale settlement. A
|
|
289
|
+
single-role replacement does not reconstruct, unregister, dispose, or reroute
|
|
290
|
+
the omitted role or change its ready/selected state, provider identity,
|
|
291
|
+
operation generation, or lifecycle. STT-only replacement also preserves TTS
|
|
292
|
+
mute and playback state; TTS replacement invalidates current TTS speech control
|
|
293
|
+
before replacing that role. The caller's signal is
|
|
294
|
+
forwarded and detached on settlement. Cancellation proves delivery suppression,
|
|
295
|
+
not that provider work stopped beyond the provider's own cancellation contract.
|
|
296
|
+
Once SDK-owned browser speech is active, synchronous route mutation fails with
|
|
297
|
+
`ARCANE_AI_BROWSER_SPEECH_ASYNC_TRANSITION_REQUIRED`; use an asynchronous
|
|
298
|
+
transition method or await `disposeBrowserSpeech()`.
|
|
299
|
+
|
|
300
|
+
Browser speech publishes these exact event values through the AI instance's
|
|
301
|
+
canonical event source. Public consumers use
|
|
302
|
+
`arcaneEvents.subscribe(type,handler,{signal})`; `handler(occurrence)` receives
|
|
303
|
+
the frozen canonical occurrence and can correlate `source:'ai'`, `instanceId`,
|
|
304
|
+
and `operationId`:
|
|
305
|
+
|
|
306
|
+
| Constant member | Stable value |
|
|
307
|
+
| --- | --- |
|
|
308
|
+
| `configurationStarted` | `ai-browser-speech-configuration-started` |
|
|
309
|
+
| `configured` | `ai-browser-speech-configured` |
|
|
310
|
+
| `configurationCancelled` | `ai-browser-speech-configuration-cancelled` |
|
|
311
|
+
| `configurationError` | `ai-browser-speech-configuration-error` |
|
|
312
|
+
| `disposed` | `ai-browser-speech-disposed` |
|
|
313
|
+
|
|
314
|
+
Canonical public details are frozen and contain `configurationId`, optional
|
|
315
|
+
`descriptor`, optional exact `code`, and `reason`. The private source-local
|
|
316
|
+
compatibility view also carries the caller-owned configuration and optional
|
|
317
|
+
error, but `AI` does not expose that source handle and the global occurrence
|
|
318
|
+
does not publish those private values. Reasons are exactly `speech-configuration-added`,
|
|
319
|
+
`speech-configuration-replaced`, `speech-configuration-cancelled`,
|
|
320
|
+
`speech-configuration-disposed`, `speech-configuration-contract-mismatch`,
|
|
321
|
+
`speech-configuration-async-transition-required`,
|
|
322
|
+
`speech-operation-options-contract-mismatch`,
|
|
323
|
+
`speech-operation-sequence-exhausted`, `speech-module-import-rejected`,
|
|
324
|
+
`speech-artifact-store-construction-rejected`,
|
|
325
|
+
`speech-provider-construction-rejected`, `speech-provider-disposal-rejected`,
|
|
326
|
+
`speech-provider-route-ownership-mismatch`,
|
|
327
|
+
`speech-provider-unregistration-rejected`, `speech-route-commit-rejected`,
|
|
328
|
+
`speech-route-rollback-rejected`, and `speech-route-view-update-rejected`.
|
|
329
|
+
Their corresponding exact public codes are the values of
|
|
330
|
+
`AI_BROWSER_SPEECH_ERROR_CODES`: `ARCANE_AI_BROWSER_SPEECH_CONFIGURATION_CANCELLED`,
|
|
331
|
+
`ARCANE_AI_BROWSER_SPEECH_CONFIGURATION_SUPERSEDED`,
|
|
332
|
+
`ARCANE_AI_BROWSER_SPEECH_CONFIGURATION_CONTRACT_MISMATCH`,
|
|
333
|
+
`ARCANE_AI_BROWSER_SPEECH_ASYNC_TRANSITION_REQUIRED`,
|
|
334
|
+
`ARCANE_AI_BROWSER_SPEECH_OPERATION_OPTIONS_CONTRACT_MISMATCH`,
|
|
335
|
+
`ARCANE_AI_BROWSER_SPEECH_OPERATION_SEQUENCE_EXHAUSTED`,
|
|
336
|
+
`ARCANE_AI_BROWSER_SPEECH_MODULE_IMPORT_REJECTED`,
|
|
337
|
+
`ARCANE_AI_BROWSER_SPEECH_ARTIFACT_STORE_CONSTRUCTION_REJECTED`,
|
|
338
|
+
`ARCANE_AI_BROWSER_SPEECH_PROVIDER_CONSTRUCTION_REJECTED`,
|
|
339
|
+
`ARCANE_AI_BROWSER_SPEECH_PROVIDER_DISPOSAL_REJECTED`,
|
|
340
|
+
`ARCANE_AI_BROWSER_SPEECH_PROVIDER_ROUTE_OWNERSHIP_MISMATCH`,
|
|
341
|
+
`ARCANE_AI_BROWSER_SPEECH_PROVIDER_UNREGISTRATION_REJECTED`,
|
|
342
|
+
`ARCANE_AI_BROWSER_SPEECH_ROUTE_COMMIT_REJECTED`,
|
|
343
|
+
`ARCANE_AI_BROWSER_SPEECH_ROUTE_ROLLBACK_REJECTED`, and
|
|
344
|
+
`ARCANE_AI_BROWSER_SPEECH_ROUTE_VIEW_UPDATE_REJECTED`.
|
|
345
|
+
|
|
346
|
+
`fetchTTS()` rejects malformed request/signal/input/model/voice/format/speed
|
|
347
|
+
boundaries with `ARCANE_AI_TTS_REQUEST_INVALID`,
|
|
348
|
+
`ARCANE_AI_TTS_SIGNAL_INVALID`, `ARCANE_AI_TTS_INPUT_INVALID`,
|
|
349
|
+
`ARCANE_AI_TTS_MODEL_INVALID`, `ARCANE_AI_TTS_MODEL_REQUIRED`,
|
|
350
|
+
`ARCANE_AI_TTS_MODEL_SELECTION_MISMATCH`, `ARCANE_AI_TTS_VOICE_INVALID`,
|
|
351
|
+
`ARCANE_AI_TTS_VOICE_REQUIRED`, `ARCANE_AI_TTS_RESPONSE_FORMAT_INVALID`, or
|
|
352
|
+
`ARCANE_AI_TTS_SPEED_INVALID`; a non-playable provider result is
|
|
353
|
+
`ARCANE_AI_TTS_PROVIDER_AUDIO_INVALID`. `fetchSTT()` uses
|
|
354
|
+
`ARCANE_AI_STT_RESPONSE_HANDLER_INVALID`, `ARCANE_AI_STT_SIGNAL_INVALID`, and
|
|
355
|
+
`ARCANE_AI_STT_PROVIDER_TRANSCRIPT_INVALID` at those exact boundaries. Owned
|
|
356
|
+
request abortion is `ARCANE_AI_REQUEST_ABORTED`.
|
|
357
|
+
|
|
358
|
+
Exact exports: `AI_BROWSER_SPEECH_CONFIGURATION_PROTOCOL`,
|
|
359
|
+
`AI_BROWSER_SPEECH_ERROR_CODES`, `AI_BROWSER_SPEECH_EVENT_TYPES`,
|
|
360
|
+
`AI_BROWSER_SPEECH_REASONS`, `AI_INITIALIZATION_ERROR_CODES`,
|
|
361
|
+
`AI_INITIALIZATION_REASONS`, `AI_READY_EVENT`, and `default`.
|
|
153
362
|
|
|
154
363
|
### Availability and normalization
|
|
155
364
|
|
|
@@ -160,11 +369,7 @@ Arcane.speech, and the Android WebView bridge. [Deep protocol details](protocols
|
|
|
160
369
|
|
|
161
370
|
### Example
|
|
162
371
|
|
|
163
|
-
|
|
164
|
-
import * as module from '/arcane/modules/AI.js';
|
|
165
|
-
|
|
166
|
-
console.log(Object.keys(module));
|
|
167
|
-
```
|
|
372
|
+
The configuration example above is the minimal one-time application flow.
|
|
168
373
|
|
|
169
374
|
## AIPreferenceRuntime.js
|
|
170
375
|
|
|
@@ -226,20 +431,73 @@ shape, but application code uses the exported singleton returned by
|
|
|
226
431
|
|
|
227
432
|
### Public surface
|
|
228
433
|
|
|
229
|
-
Exact exports: `
|
|
230
|
-
`
|
|
434
|
+
Exact exports: `AI_MODEL_AUTHORITY_PROTOCOL`, `AI_PROVIDER_PROTOCOL`,
|
|
435
|
+
`AI_PROVIDER_RUNTIME_PROTOCOL`, `AIProviderRuntime`, `aiProviderRuntime`, and
|
|
231
436
|
`getAIProviderRuntime`.
|
|
232
437
|
|
|
233
|
-
The singleton exposes
|
|
234
|
-
|
|
235
|
-
`
|
|
236
|
-
`
|
|
438
|
+
The singleton exposes read-only `protocol`, `configured`, and `speechMuted`;
|
|
439
|
+
`register(provider)`; `unregister(role,providerId,expectedProvider=null)`;
|
|
440
|
+
`hasProvider(role,providerId)`; `ownsProvider(role,expectedProvider)`;
|
|
441
|
+
`providerIdentity(role,providerId)`; `selection(role,options={})`;
|
|
442
|
+
`ownsSelection(role,providerId,options={})`;
|
|
443
|
+
`validateConfiguration(value)`; `validateSpeechConfiguration(value)`;
|
|
444
|
+
`configure(value)`; `configureSpeech(value)`;
|
|
445
|
+
`replaceSpeechProvider(role,value)`; `replaceSpeechProviders(value)`;
|
|
446
|
+
`configureFromTuple(tuple)`;
|
|
447
|
+
`status(role=null)`; `catalog(role)`;
|
|
448
|
+
`inspect(role,options={})`; `start(options)`; `load(role,options={})`;
|
|
449
|
+
`unload(role,options={})`; `dispose(role,options={})`;
|
|
450
|
+
`disposeAll(options={})`; `cancel(role)`; `request(role,options={})`;
|
|
451
|
+
`chat(payload,options={})`; `stream(payload,options={})`;
|
|
452
|
+
`transcribe(payload,options={})`; `synthesize(payload,options={})`; and
|
|
453
|
+
`setSpeechMuted(muted)`. Provider payloads must
|
|
237
454
|
be data-only; callbacks, accessors, symbols, cycles, and excessive nesting are
|
|
238
455
|
rejected at the provider boundary.
|
|
239
456
|
|
|
240
|
-
`
|
|
241
|
-
|
|
242
|
-
|
|
457
|
+
Selection options admit `localOnly=false`; inspection admits
|
|
458
|
+
`{localOnly=false,signal=null}`; startup admits
|
|
459
|
+
`{startMuted=true,startTranscription=false,signal=null}` (including an omitted
|
|
460
|
+
`options` value); load admits `{signal=null,localOnly=false}`; unload, dispose,
|
|
461
|
+
and dispose-all admit `{signal=null}`. Request requires the exact
|
|
462
|
+
`{operation,payload,localOnly,signal}` options record; the four role-specific
|
|
463
|
+
request helpers admit `{localOnly=false,signal=null}`. Configuration `value`
|
|
464
|
+
records are the closed `{llm,stt,tts}`, `{stt,tts}`, or
|
|
465
|
+
`{provider,routes,expectedProvider}` and
|
|
466
|
+
`{providers,routes,expectedProviders}` shapes described below.
|
|
467
|
+
`configureFromTuple()` accepts exactly six provider/model preference entries.
|
|
468
|
+
|
|
469
|
+
`register()` returns the provider's single unregister closure; caller-
|
|
470
|
+
registered providers remain caller-owned. The high-level
|
|
471
|
+
`AI.configureBrowserSpeech()` boundary is different: AI constructs, registers,
|
|
472
|
+
atomically replaces, unregisters, and disposes those two SDK-owned providers.
|
|
473
|
+
`status()` is the sticky frozen AIRuntimeState snapshot (or one role record),
|
|
474
|
+
while `catalog()` synchronously returns frozen provider/model admissions and
|
|
475
|
+
never loads or downloads a model. `load()` forwards provider progress into the
|
|
476
|
+
sticky role record; `unload()` and `dispose()` abort owned work, await exposed
|
|
477
|
+
settlement, and verify provider status before publishing terminal state.
|
|
478
|
+
|
|
479
|
+
`validateSpeechConfiguration(value)` returns one frozen two-role selection
|
|
480
|
+
record without committing it, where `value` is the closed `{stt,tts}` record.
|
|
481
|
+
`configureSpeech(value)` accepts the same record, requires both speech roles to
|
|
482
|
+
own no ready/load/unload/dispose or request work, commits only STT/TTS, restores
|
|
483
|
+
muted speech admission, and returns the frozen selection record. The current LLM
|
|
484
|
+
routes, selection, readiness, operation generation, and sticky state remain
|
|
485
|
+
unchanged. A malformed top-level, route, or selection record preserves the
|
|
486
|
+
compatibility code
|
|
487
|
+
`ARCANE_AI_PROVIDER_RUNTIME_INVALID` and adds exact reason
|
|
488
|
+
`speech-configuration-contract-mismatch`; runtime-disposed, reentrant,
|
|
489
|
+
role-busy, and provider-locality failures retain their existing exact codes.
|
|
490
|
+
|
|
491
|
+
`replaceSpeechProvider(role,value)` accepts only `stt` or `tts` and atomically
|
|
492
|
+
replaces exactly that unloaded role using the closed
|
|
493
|
+
`{provider,routes,expectedProvider}` record. A null `provider` with empty routes
|
|
494
|
+
removes that role and requires its exact non-null expected provider. The method preserves the omitted role's
|
|
495
|
+
provider registration, routes, selection, readiness, generation, sticky state,
|
|
496
|
+
owned lifecycle work, and TTS mute state. `replaceSpeechProviders(value)` keeps
|
|
497
|
+
the existing atomic two-role boundary for a coordinated STT/TTS replacement.
|
|
498
|
+
|
|
499
|
+
`start(options)` waits for prior speech-state and role unload work, applies the
|
|
500
|
+
requested initial mute state, and returns the `startAIRuntime()` control handle
|
|
243
501
|
`{barrier,settled,cancel}`. Startup does not request selected STT unless the
|
|
244
502
|
caller explicitly opts in; it does not force an independently active STT role
|
|
245
503
|
back to unloaded. The barrier and settled promises describe provider-startup
|
|
@@ -259,15 +517,16 @@ request ownership is active.
|
|
|
259
517
|
|
|
260
518
|
### Availability and normalization
|
|
261
519
|
|
|
262
|
-
**Cross-host runtime with provider-specific execution.**
|
|
263
|
-
|
|
264
|
-
legacy speech adapters
|
|
265
|
-
|
|
266
|
-
adapters may be supplied externally only when they implement the same
|
|
520
|
+
**Cross-host runtime with provider-specific execution.** The SDK source ships
|
|
521
|
+
the browser-WASM LLM and browser Whisper/Kokoro adapters and supplies the
|
|
522
|
+
narrow AI.js legacy OpenAI/Ollama/Core-speech adapters; other native, Core, or
|
|
523
|
+
cloud adapters may be supplied externally only when they implement the same
|
|
267
524
|
`arcane-ai-provider/2` boundary. A
|
|
268
525
|
provider must prove a matching `arcane-ai-model-authority/1` inspection before load.
|
|
269
526
|
`localOnly` routing fails closed; it never selects a cloud or non-local route as
|
|
270
|
-
a fallback.
|
|
527
|
+
a fallback. A missing or mismatched explicit local-only route rejects load or
|
|
528
|
+
request admission with `AI_LOCAL_MODEL_REQUIRED`. Role lifecycle and stream
|
|
529
|
+
cleanup are normalized, while the
|
|
271
530
|
selected provider retains its own capability, permission, download, and model
|
|
272
531
|
requirements. [Deep protocol details](protocols.md#portable-ai-provider-runtime).
|
|
273
532
|
|
|
@@ -338,15 +597,21 @@ observable without exposing provider transports in application code.
|
|
|
338
597
|
|
|
339
598
|
### Public surface
|
|
340
599
|
|
|
341
|
-
Exact exports: `
|
|
342
|
-
`
|
|
343
|
-
`
|
|
344
|
-
`
|
|
345
|
-
`
|
|
346
|
-
`
|
|
600
|
+
Exact exports: `AI_RUNTIME_INTENT_EVENT`, `AI_RUNTIME_PROTOCOL`,
|
|
601
|
+
`AI_RUNTIME_ROLES`, `AI_RUNTIME_STARTUP_EVENT`, `AI_RUNTIME_STATES`,
|
|
602
|
+
`AI_RUNTIME_STATE_EVENT`, `aiRuntimeEvents`, `getAIRuntimeState`,
|
|
603
|
+
`publishAIRuntimeRoleState`, `publishAIRuntimeRolesState`,
|
|
604
|
+
`requestAIRuntimeIntent`, `startAIRuntime`, `subscribeAIRuntimeIntents`, and
|
|
605
|
+
`subscribeAIRuntimeState`.
|
|
347
606
|
|
|
348
607
|
Each role record is exactly `{role,state,providerId,modelId,localOnly,loaded,
|
|
349
608
|
busy,operationId,progress,error}`.
|
|
609
|
+
`subscribeAIRuntimeState(listener,{signal=null,emitCurrent=true})` installs its
|
|
610
|
+
subscription and synchronously replays the current frozen snapshot by default;
|
|
611
|
+
`subscribeAIRuntimeIntents(listener,{signal=null})` is future-only. Both return
|
|
612
|
+
one idempotent unsubscribe/dispose closure. `aiRuntimeEvents` is a deprecated,
|
|
613
|
+
state-free EventTarget compatibility view over the same canonical source; it is
|
|
614
|
+
not a second authority and owns no listener registry.
|
|
350
615
|
`startAIRuntime({startMuted=true,startTranscription=false,signal})` returns
|
|
351
616
|
`{barrier,settled,cancel}`: `barrier` settles for text chat, while `settled`
|
|
352
617
|
covers every requested role. Muted startup does not request TTS, and STT startup
|
|
@@ -363,6 +628,11 @@ does not grant a native capability, prove browser support, or load a provider.
|
|
|
363
628
|
`arcane-ai-runtime-startup-settled` reports the LLM/text-chat `barrier`.
|
|
364
629
|
Await the returned `handle.settled` promise for every role requested by that
|
|
365
630
|
startup; the all-role settlement has no separate public event.
|
|
631
|
+
Intent records are exactly `{role,action,reason}` where roles are `llm`, `stt`,
|
|
632
|
+
or `tts`; actions are `load`, `unload`, or `dispose`; and reasons are `startup`,
|
|
633
|
+
`user`, or `teardown`. Invalid closed records fail with the stable prefix
|
|
634
|
+
`ARCANE_AI_RUNTIME_STATE_INVALID`; startup cancellation is an `AbortError` with
|
|
635
|
+
code `ARCANE_AI_REQUEST_ABORTED`.
|
|
366
636
|
|
|
367
637
|
### Example
|
|
368
638
|
|
|
@@ -413,7 +683,8 @@ Fetches an injectable HTTP JSON model with parser, cache, redacted public endpoi
|
|
|
413
683
|
|
|
414
684
|
default `ApiModelDatabase`; `setEndpoint()`, `fetch()`, `cached()`; emits `api-model-request`, `api-model-success`, and `api-model-error`.
|
|
415
685
|
|
|
416
|
-
Exact exports: `
|
|
686
|
+
Exact exports: `API_MODEL_ERRORS`, `API_MODEL_EVENTS`, `appendParameters`,
|
|
687
|
+
`default`, `publicEndpoint`.
|
|
417
688
|
|
|
418
689
|
### Availability and normalization
|
|
419
690
|
|
|
@@ -581,7 +852,9 @@ Runs a fixed sequential browser test list with cooperative abort, per-test timeo
|
|
|
581
852
|
|
|
582
853
|
default `BrowserTestSuite`; `list()`, `run()`; emits suite/test start/result/complete events.
|
|
583
854
|
|
|
584
|
-
Exact exports: `
|
|
855
|
+
Exact exports: `BROWSER_TEST_SUITE_ERROR_CODES`,
|
|
856
|
+
`BROWSER_TEST_SUITE_EVENT_TYPES`, `BROWSER_TEST_SUITE_REASONS`,
|
|
857
|
+
`assertionError`, `default`, `skipError`.
|
|
585
858
|
|
|
586
859
|
### Availability and normalization
|
|
587
860
|
|
|
@@ -603,13 +876,40 @@ Evaluates bounded arithmetic, powers, constants, and common functions without `e
|
|
|
603
876
|
|
|
604
877
|
### Public surface
|
|
605
878
|
|
|
606
|
-
|
|
879
|
+
`new CalculatorEngine()` exposes synchronous
|
|
880
|
+
`calculate(expression): Calculation`,
|
|
881
|
+
`addEventListener(type,listener,options): void`,
|
|
882
|
+
`removeEventListener(type,listener,options): void`,
|
|
883
|
+
`on(type,listener,options): unsubscribe`,
|
|
884
|
+
`dispatchEvent(event): boolean`, and idempotent
|
|
885
|
+
`dispose(): boolean` / `destroy(): boolean`. `evaluateExpression(input): number`
|
|
886
|
+
remains the parser-only helper. `CALCULATOR_ENGINE_ERROR_CODES` is one frozen
|
|
887
|
+
record containing the stable `disposed`, `input`, `syntax`, `domain`, and
|
|
888
|
+
`evaluation` codes.
|
|
607
889
|
|
|
608
|
-
Exact exports: `
|
|
890
|
+
Exact exports: `CALCULATOR_ENGINE_ERROR_CODES`, `default`,
|
|
891
|
+
`evaluateExpression`.
|
|
609
892
|
|
|
610
893
|
### Availability and normalization
|
|
611
894
|
|
|
612
|
-
**Cross-host.**
|
|
895
|
+
**Cross-host.** Each engine owns one `calculator-engine` source on the realm's
|
|
896
|
+
branded `globalThis.arcaneEvents`. `calculator-result` publishes frozen public
|
|
897
|
+
detail `{result}`; the legacy instance listener receives the same `Calculation`
|
|
898
|
+
object returned by `calculate()`. `calculator-error` publishes frozen public
|
|
899
|
+
detail `{code}`; the legacy listener receives frozen
|
|
900
|
+
`{expression,error}` while `calculate()` rethrows that same `Error`. Both
|
|
901
|
+
occurrences carry one source-instance `operationId`. Listener callbacks are
|
|
902
|
+
synchronous observations; their failures are reported by the central event
|
|
903
|
+
authority and do not rewrite calculation settlement. Listener registration
|
|
904
|
+
supports `{once,signal}` and its returned unsubscribe also exposes `.dispose()`.
|
|
905
|
+
Disposal removes instance listeners and rejects later calculations with
|
|
906
|
+
`ARCANE_CALCULATOR_ENGINE_DISPOSED`. Invalid expression input, syntax, numeric
|
|
907
|
+
domain, and unexpected evaluation boundaries use
|
|
908
|
+
`ARCANE_CALCULATOR_EXPRESSION_INPUT_INVALID`,
|
|
909
|
+
`ARCANE_CALCULATOR_EXPRESSION_SYNTAX_INVALID`,
|
|
910
|
+
`ARCANE_CALCULATOR_EXPRESSION_DOMAIN_INVALID`, and
|
|
911
|
+
`ARCANE_CALCULATOR_EXPRESSION_EVALUATION_FAILED`. Transport: in-process only.
|
|
912
|
+
[Deep protocol details](protocols.md).
|
|
613
913
|
|
|
614
914
|
### Example
|
|
615
915
|
|
|
@@ -702,7 +1002,7 @@ Binds shared inbox, conversation, settings, theme, and provider workflows into o
|
|
|
702
1002
|
|
|
703
1003
|
default controller with `start()`, `bind()`, `configure()`, `refresh()`, `select()`, `send()`, and settings actions.
|
|
704
1004
|
|
|
705
|
-
Exact exports: `default`.
|
|
1005
|
+
Exact exports: `COMMUNICATION_APP_CONTROLLER_ERROR_CODES`, `default`.
|
|
706
1006
|
|
|
707
1007
|
### Availability and normalization
|
|
708
1008
|
|
|
@@ -726,7 +1026,9 @@ Fans out provider refresh/send operations and aggregates normalized threads/mess
|
|
|
726
1026
|
|
|
727
1027
|
default `CommunicationHub`; provider enablement, `refresh()`, `messages()`, and `send()`.
|
|
728
1028
|
|
|
729
|
-
Exact exports: `
|
|
1029
|
+
Exact exports: `COMMUNICATION_HUB_ERROR_CODES`, `COMMUNICATION_HUB_EVENTS`,
|
|
1030
|
+
`COMMUNICATION_HUB_REFRESH_REASONS`, `COMMUNICATION_HUB_REFRESH_STATES`, and
|
|
1031
|
+
`default`.
|
|
730
1032
|
|
|
731
1033
|
### Availability and normalization
|
|
732
1034
|
|
|
@@ -792,17 +1094,48 @@ console.log(Object.keys(module));
|
|
|
792
1094
|
|
|
793
1095
|
### Overview
|
|
794
1096
|
|
|
795
|
-
Owns normalized configuration/value contracts shared
|
|
1097
|
+
Owns normalized configuration/value contracts and shared explicit STT activation
|
|
1098
|
+
behavior for chart, dashboard, Markdown, and voice components.
|
|
796
1099
|
|
|
797
1100
|
### Public surface
|
|
798
1101
|
|
|
799
|
-
|
|
1102
|
+
Constant sets plus normalization, formatting, and explicit STT activation
|
|
1103
|
+
helpers. `createSTTActivationController({host,button,onChange,EventClass=CustomEvent})`
|
|
1104
|
+
consumes only normalized
|
|
1105
|
+
[`AIRuntimeState`](#airuntimestatejs) `stt` role records. Its frozen controller
|
|
1106
|
+
exposes `action`, `error`, `label`, `pending`, `selected`, `status`, `title`, and
|
|
1107
|
+
`visible` getters plus `request(action)`, `synchronize(role)`, and `destroy()`.
|
|
1108
|
+
`host` supplies `dispatchEvent(event)` and `requestSTTActivation(intent)`;
|
|
1109
|
+
`button` supplies `addEventListener()` and `removeEventListener()`; and
|
|
1110
|
+
`onChange()` is called whenever presentation should be rendered again. Browser
|
|
1111
|
+
callers use the default `CustomEvent`; non-DOM callers must inject a compatible
|
|
1112
|
+
`EventClass` constructor.
|
|
800
1113
|
|
|
801
|
-
|
|
1114
|
+
`request('load'|'unload')` emits the cancelable
|
|
1115
|
+
`speech-stt-activation-request` event with frozen `{intent,state}` before it
|
|
1116
|
+
invokes `host.requestSTTActivation(intent)`. Callback failure emits
|
|
1117
|
+
`speech-stt-activation-error` with frozen `{request,error,message}`. Syncing
|
|
1118
|
+
sticky state only changes the controller's observation and presentation; it
|
|
1119
|
+
never emits a lifecycle intent, chooses a provider, or starts a download.
|
|
1120
|
+
`destroy()` removes its button listener and suppresses late callback effects.
|
|
1121
|
+
|
|
1122
|
+
Exact exports: `CHART_LABELS`, `DASHBOARD_LABELS`, `MARKDOWN_FORMATS`,
|
|
1123
|
+
`MARKDOWN_LABELS`, `STT_ACTIVATION_ERROR_CODES`,
|
|
1124
|
+
`STT_ACTIVATION_EVENT_TYPES`, `STT_ACTIVATION_REASONS`, `VOICE_LABELS`,
|
|
1125
|
+
`VOICE_MESSAGES`, `appendTranscription`, `applyMarkdownFormat`,
|
|
1126
|
+
`createSTTActivationController`, `effectiveDashboardVisibility`,
|
|
1127
|
+
`normalizeChartOptions`, `normalizeChartRows`, `normalizeDashboardDefinitions`,
|
|
1128
|
+
`normalizeDashboardOptions`, `normalizeDashboardVisibility`,
|
|
1129
|
+
`normalizeMarkdownFormats`, `normalizeMarkdownOptions`, and
|
|
1130
|
+
`normalizeVoiceOptions`.
|
|
802
1131
|
|
|
803
1132
|
### Availability and normalization
|
|
804
1133
|
|
|
805
|
-
**Cross-host
|
|
1134
|
+
**Cross-host with an injected event constructor outside DOM hosts.** Fully
|
|
1135
|
+
normalized labels, rows, definitions, visibility, formats, editor and voice
|
|
1136
|
+
options, plus capability-neutral STT activation intent and presentation state.
|
|
1137
|
+
Provider authority and lifecycle execution remain with the configured runtime
|
|
1138
|
+
owner. Transport: In-process only. [Deep protocol details](protocols.md).
|
|
806
1139
|
|
|
807
1140
|
### Example
|
|
808
1141
|
|
|
@@ -937,7 +1270,15 @@ Owns conversation limits, control messages, submission barriers, elapsed formatt
|
|
|
937
1270
|
|
|
938
1271
|
default `ConversationTimebox`, `ConversationSubmissionBarrier`, constants and control helpers.
|
|
939
1272
|
|
|
940
|
-
Exact exports: `
|
|
1273
|
+
Exact exports: `CONVERSATION_TIMEBOX_ERROR_CODES`,
|
|
1274
|
+
`CONVERSATION_TIMEBOX_EVENT_TYPES`, `CONVERSATION_TIMEBOX_LIMIT_MESSAGE`,
|
|
1275
|
+
`CONVERSATION_TIMEBOX_OPENING_INSTRUCTION`, `CONVERSATION_TIMEBOX_REASONS`,
|
|
1276
|
+
`CONVERSATION_TIMEBOX_TOOL_NAME`, `ConversationSubmissionBarrier`,
|
|
1277
|
+
`appendConversationTimeboxOpeningInstruction`, `consumeConversationTimeboxCall`,
|
|
1278
|
+
`conversationTimeboxSubmissionKey`, `conversationTimeboxTool`,
|
|
1279
|
+
`createConversationTimeboxControlMessage`, `default`,
|
|
1280
|
+
`formatConversationElapsed`, `normalizeConversationTimeboxCommand`, and
|
|
1281
|
+
`requireConversationTimeboxDelivery`.
|
|
941
1282
|
|
|
942
1283
|
### Availability and normalization
|
|
943
1284
|
|
|
@@ -1009,7 +1350,7 @@ Provides app-scoped localStorage tables, batch reads/writes, filtering, deletion
|
|
|
1009
1350
|
|
|
1010
1351
|
default `DBLS`; installs `window.dbls`, emits `dbls-ready`; CRUD/batch/key APIs.
|
|
1011
1352
|
|
|
1012
|
-
Exact exports: `default`.
|
|
1353
|
+
Exact exports: `DBLS_EVENT_TYPES`, `DBLS_REASONS`, `default`.
|
|
1013
1354
|
|
|
1014
1355
|
### Availability and normalization
|
|
1015
1356
|
|
|
@@ -1033,7 +1374,7 @@ Provides app-scoped OPFS tables, worker I/O, backup/restore, compression, and CR
|
|
|
1033
1374
|
|
|
1034
1375
|
default `DBOPFS`; installs `window.dbopfs`, emits `dbopfs-ready`; table/file/backup APIs.
|
|
1035
1376
|
|
|
1036
|
-
Exact exports: `default`.
|
|
1377
|
+
Exact exports: `DBOPFS_EVENT_TYPES`, `DBOPFS_REASONS`, `default`.
|
|
1037
1378
|
|
|
1038
1379
|
### Availability and normalization
|
|
1039
1380
|
|
|
@@ -1058,8 +1399,8 @@ or search; applications call `bootstrap()` deliberately.
|
|
|
1058
1399
|
|
|
1059
1400
|
### Public surface
|
|
1060
1401
|
|
|
1061
|
-
Exact exports:
|
|
1062
|
-
`
|
|
1402
|
+
Exact exports: `DBOPFSDocumentLibrary`, `createDBOPFSDocumentLibrary`,
|
|
1403
|
+
`default`, and `normalizeDBOPFSDocumentSchema`.
|
|
1063
1404
|
|
|
1064
1405
|
`new DBOPFSDocumentLibrary({concurrency,db,maxCorpusCharacters,
|
|
1065
1406
|
maxDocumentCharacters,maxSearchCharacters,schema})` exposes `schema`,
|
|
@@ -1083,7 +1424,7 @@ source body as implicit authority, and never persists a caller-owned body.
|
|
|
1083
1424
|
**Browser or compatible host with an injected DBOPFS adapter.** The adapter
|
|
1084
1425
|
keeps the existing `get`, `set`, `getAllKeys`, and `delete` method names; Node
|
|
1085
1426
|
can use the same class only through an explicitly imported runtime module and a
|
|
1086
|
-
compatible storage adapter; SDK `0.
|
|
1427
|
+
compatible storage adapter; SDK `0.3.0` publishes no Node package subpath or
|
|
1087
1428
|
Node storage implementation for it. Bootstrap uses a bounded concurrent
|
|
1088
1429
|
generation, commits its manifest last, cleans partial data on failure, and
|
|
1089
1430
|
rejects case-colliding IDs. Search
|
|
@@ -1216,11 +1557,10 @@ context excerpts for caller-owned document records.
|
|
|
1216
1557
|
|
|
1217
1558
|
### Public surface
|
|
1218
1559
|
|
|
1219
|
-
Exact exports: `DOCUMENT_SEARCH_FIELD_ORDER`,
|
|
1220
|
-
`
|
|
1221
|
-
`
|
|
1222
|
-
|
|
1223
|
-
`scoreDocumentLexicalIndex()`.
|
|
1560
|
+
Exact exports: `DOCUMENT_SEARCH_FIELD_ORDER`, `DocumentLexicalSearch`,
|
|
1561
|
+
`createDocumentLexicalIndex`, `default`, `documentContextExcerpt`,
|
|
1562
|
+
`documentSearchTokens`, `normalizedDocumentSearchText`, `scoreDocumentBody`,
|
|
1563
|
+
and `scoreDocumentLexicalIndex`.
|
|
1224
1564
|
|
|
1225
1565
|
`new DocumentLexicalSearch(records,{maxResults=20})` exposes
|
|
1226
1566
|
`rank(query,{kinds,tags})` and `search(query,{kinds,limit,tags})`.
|
|
@@ -1283,7 +1623,9 @@ Normalizes global errors/rejections, fingerprints and deduplicates incidents, pe
|
|
|
1283
1623
|
|
|
1284
1624
|
default `Errors`; event normalizers/fingerprint plus lifecycle, capture, delivery and teardown methods.
|
|
1285
1625
|
|
|
1286
|
-
Exact exports: `
|
|
1626
|
+
Exact exports: `GLOBAL_ERROR_EVENT_CODES`, `GLOBAL_ERROR_EVENT_TYPES`,
|
|
1627
|
+
`GLOBAL_ERROR_REASONS`, `default`, `fingerprintIncident`,
|
|
1628
|
+
`normalizeErrorEvent`, and `normalizeRejectionEvent`.
|
|
1287
1629
|
|
|
1288
1630
|
### Availability and normalization
|
|
1289
1631
|
|
|
@@ -1427,7 +1769,10 @@ Coordinates local-AI status component checks, ensured recovery, availability pro
|
|
|
1427
1769
|
|
|
1428
1770
|
`createLocalAIReadinessController()`, `availabilityFromReport()`.
|
|
1429
1771
|
|
|
1430
|
-
Exact exports: `
|
|
1772
|
+
Exact exports: `LOCAL_AI_READINESS_CONTROLLER_ERROR_CODES`,
|
|
1773
|
+
`LOCAL_AI_READINESS_CONTROLLER_EVENT_TYPES`,
|
|
1774
|
+
`LOCAL_AI_READINESS_CONTROLLER_REASONS`, `availabilityFromReport`, and
|
|
1775
|
+
`createLocalAIReadinessController`.
|
|
1431
1776
|
|
|
1432
1777
|
### Availability and normalization
|
|
1433
1778
|
|
|
@@ -1473,6 +1818,115 @@ import * as module from '/arcane/modules/Mail.js';
|
|
|
1473
1818
|
console.log(Object.keys(module));
|
|
1474
1819
|
```
|
|
1475
1820
|
|
|
1821
|
+
## MailOutbox.mjs
|
|
1822
|
+
|
|
1823
|
+
### Overview
|
|
1824
|
+
|
|
1825
|
+
Persists each bounded provider-neutral mail report before delivery and owns its
|
|
1826
|
+
idempotent enqueue, FIFO drain, retry-window, terminal-state, reconciliation,
|
|
1827
|
+
and explicit invalid-record maintenance lifecycle. It selects no mail provider,
|
|
1828
|
+
recipient, retention policy, retry timer, or transport fallback.
|
|
1829
|
+
|
|
1830
|
+
### Public surface
|
|
1831
|
+
|
|
1832
|
+
Exact exports: `MAIL_OUTBOX_ACCEPTANCE_AUTHORITIES`,
|
|
1833
|
+
`MAIL_OUTBOX_IDEMPOTENCY_WINDOW_MS`, `MAIL_OUTBOX_PROTOCOL`,
|
|
1834
|
+
`MAIL_OUTBOX_STATES`, `MAIL_OUTBOX_TABLE`, `MailOutbox`, `createMailOutbox`, and
|
|
1835
|
+
`default`.
|
|
1836
|
+
|
|
1837
|
+
```text
|
|
1838
|
+
new MailOutbox({
|
|
1839
|
+
storage,
|
|
1840
|
+
deliver,
|
|
1841
|
+
clock=Date.now,
|
|
1842
|
+
isOnline=()=>globalThis.navigator?.onLine!==false,
|
|
1843
|
+
lockManager=undefined,
|
|
1844
|
+
onlineTarget=typeof globalThis.addEventListener==='function'?globalThis:null,
|
|
1845
|
+
onRecordCommitted=null,
|
|
1846
|
+
maxAttemptsPerDrain=16,
|
|
1847
|
+
maxInvalidRecords=128,
|
|
1848
|
+
maxRecords=512,
|
|
1849
|
+
maxReportBytes=786432,
|
|
1850
|
+
quarantineTable='mail_outbox_quarantine',
|
|
1851
|
+
table=MAIL_OUTBOX_TABLE
|
|
1852
|
+
}={})
|
|
1853
|
+
```
|
|
1854
|
+
|
|
1855
|
+
`storage` must expose `get()`, `set()`, and `getAllKeys()`; explicit deletion or
|
|
1856
|
+
quarantine additionally requires `delete()`. `lockManager` must expose the Web
|
|
1857
|
+
Locks-compatible `request()` contract. The injected
|
|
1858
|
+
`deliver({report,reportKey,serializedReport,signal})` callback receives the
|
|
1859
|
+
frozen parsed report, its stable idempotency key, the exact stored JSON string,
|
|
1860
|
+
and the caller-owned signal. Omitted `lockManager` resolves first from storage
|
|
1861
|
+
and then from `navigator.locks`. A delivery result must identify a valid
|
|
1862
|
+
`requestId` and one of `accepted`, `delivery_uncertain`,
|
|
1863
|
+
`temporarily_rejected`, `permanently_rejected`, or `partially_accepted`;
|
|
1864
|
+
accepted results additionally require a provider ID or the admitted
|
|
1865
|
+
`arcane-core-mail-send-v1` acceptance authority.
|
|
1866
|
+
|
|
1867
|
+
Read-only getters are `started`, `invalidRecords`, and `lastBackgroundError`.
|
|
1868
|
+
Methods are `get(key)`, `list()`, `audit()`, `deleteInvalid(fileName)`,
|
|
1869
|
+
`repairInvalid(fileName,replacement)`,
|
|
1870
|
+
`quarantineInvalid({limit=64}={})`,
|
|
1871
|
+
`enqueue({report,reportKey}={}, {attempt=true,signal=null}={})`,
|
|
1872
|
+
`drain({reason='manual',signal=null}={})`, `start({signal=null}={})`, and
|
|
1873
|
+
`stop()`. `createMailOutbox(options)` returns `new MailOutbox(options)`.
|
|
1874
|
+
|
|
1875
|
+
Every returned durable record is deeply frozen and contains exactly
|
|
1876
|
+
`{protocol,reportKey,serializedReport,state,createdAt,updatedAt,firstAttemptAt,
|
|
1877
|
+
lastAttemptAt,nextAttemptAt,attempts,result,failure}`. Protocol is
|
|
1878
|
+
`arcane-mail-outbox/1`; the default table is `mail_outbox`; the idempotency
|
|
1879
|
+
window is 86,400,000 milliseconds. States are exactly `queued`, `sending`,
|
|
1880
|
+
`retry_wait`, `accepted`, `failed`, and `reconciliation_required`. Accepted
|
|
1881
|
+
means provider or admitted Core acceptance, not inbox delivery.
|
|
1882
|
+
|
|
1883
|
+
`enqueue()` serializes same-instance persistence and binds one report key to one
|
|
1884
|
+
exact serialized body. `drain()` runs or joins one bounded instance drain under
|
|
1885
|
+
an exclusive shared lock and attempts at most 16 records by default. Startup,
|
|
1886
|
+
an owned `online` listener, or an explicit call may trigger work; there is no
|
|
1887
|
+
polling or retry timer. Abort before the delivery call prevents that call, and a
|
|
1888
|
+
caller joining an existing drain may stop waiting without cancelling the shared
|
|
1889
|
+
drain. Once an accepted result is committed, it outranks a racing cancellation;
|
|
1890
|
+
cancellation never claims an admitted provider attempt stopped. An interrupted
|
|
1891
|
+
or ambiguous attempt remains a same-key retry inside the 24-hour window and
|
|
1892
|
+
becomes `reconciliation_required` when automatic retry would risk a duplicate.
|
|
1893
|
+
`stop()` aborts only the owned online drain, removes its listener, preserves
|
|
1894
|
+
durable records, and returns the instance.
|
|
1895
|
+
|
|
1896
|
+
`audit()` reports valid records plus bounded invalid-file metadata. Repair,
|
|
1897
|
+
deletion, and quarantine are explicit, revalidate the selected file under the
|
|
1898
|
+
table lock, and never infer destructive authority from a storage read failure.
|
|
1899
|
+
`onRecordCommitted(record)` is an observational callback after each durable
|
|
1900
|
+
write; callback failure cannot change the committed operation result.
|
|
1901
|
+
|
|
1902
|
+
### Availability and normalization
|
|
1903
|
+
|
|
1904
|
+
**Browser/native WebView or compatible injected host.** The default application
|
|
1905
|
+
integration uses DBOPFS-compatible durable storage and `navigator.locks`; an
|
|
1906
|
+
alternate adapter owns its own durability claim and must provide equivalent
|
|
1907
|
+
storage and shared-lock semantics. Frozen records, bounds, state transitions,
|
|
1908
|
+
retry/reconciliation classification, invalid-record maintenance, and
|
|
1909
|
+
AbortSignal admission/join cancellation are normalized. Storage, lock,
|
|
1910
|
+
online-check, and injected-delivery failures remain visible through concrete
|
|
1911
|
+
`MAIL_OUTBOX_*` codes. Transport: injected durable storage, Web Locks,
|
|
1912
|
+
AbortSignal, optional online EventTarget, and an injected delivery callback.
|
|
1913
|
+
[Deep protocol details](mail.md#durable-send-semantics).
|
|
1914
|
+
|
|
1915
|
+
### Example
|
|
1916
|
+
|
|
1917
|
+
```javascript
|
|
1918
|
+
import {createMailOutbox} from '/arcane/modules/MailOutbox.mjs';
|
|
1919
|
+
|
|
1920
|
+
const outbox = createMailOutbox({storage, deliver});
|
|
1921
|
+
await outbox.start({signal});
|
|
1922
|
+
const record = await outbox.enqueue(
|
|
1923
|
+
{report, reportKey: 'report-20260827-001'},
|
|
1924
|
+
{attempt: true, signal}
|
|
1925
|
+
);
|
|
1926
|
+
console.log(record.state);
|
|
1927
|
+
outbox.stop();
|
|
1928
|
+
```
|
|
1929
|
+
|
|
1476
1930
|
## MailTransport.mjs
|
|
1477
1931
|
|
|
1478
1932
|
### Overview
|
|
@@ -1481,9 +1935,12 @@ Sends one bounded mail report to a normalized HTTP(S) endpoint with timeout and
|
|
|
1481
1935
|
|
|
1482
1936
|
### Public surface
|
|
1483
1937
|
|
|
1484
|
-
Timeout/size constants, `
|
|
1938
|
+
Timeout/size constants, `MailTransportError`, `normalizeMailEndpoint()`,
|
|
1939
|
+
`serializeMailReport()`, and `sendMailReport()`.
|
|
1485
1940
|
|
|
1486
|
-
Exact exports: `DEFAULT_MAIL_REQUEST_TIMEOUT_MS`, `MAX_MAIL_RESPONSE_BYTES`,
|
|
1941
|
+
Exact exports: `DEFAULT_MAIL_REQUEST_TIMEOUT_MS`, `MAX_MAIL_RESPONSE_BYTES`,
|
|
1942
|
+
`MailTransportError`, `normalizeMailEndpoint`, `serializeMailReport`,
|
|
1943
|
+
`sendMailReport`.
|
|
1487
1944
|
|
|
1488
1945
|
### Availability and normalization
|
|
1489
1946
|
|
|
@@ -1627,7 +2084,8 @@ Provides the first-class Arcane Ollama client without direct access to localhost
|
|
|
1627
2084
|
|
|
1628
2085
|
`Ollama`, singleton/default `ollama`; 24 methods; installs `globalThis.arcaneOllama`, emits `arcane-ollama-ready`.
|
|
1629
2086
|
|
|
1630
|
-
Exact exports: `Ollama`, `default`,
|
|
2087
|
+
Exact exports: `OLLAMA_EVENT_TYPES`, `OLLAMA_REASONS`, `Ollama`, `default`,
|
|
2088
|
+
and `ollama`.
|
|
1631
2089
|
|
|
1632
2090
|
### Availability and normalization
|
|
1633
2091
|
|
|
@@ -1699,7 +2157,8 @@ Searches and loads Open-Meteo data into frozen Arcane weather entities.
|
|
|
1699
2157
|
|
|
1700
2158
|
Endpoint constants, default provider, `mapForecast()`; search/load methods and lifecycle events.
|
|
1701
2159
|
|
|
1702
|
-
Exact exports: `OPEN_METEO_ENDPOINTS`, `
|
|
2160
|
+
Exact exports: `OPEN_METEO_ENDPOINTS`, `OPEN_METEO_WEATHER_ERRORS`,
|
|
2161
|
+
`OPEN_METEO_WEATHER_EVENTS`, `default`, and `mapForecast`.
|
|
1703
2162
|
|
|
1704
2163
|
### Availability and normalization
|
|
1705
2164
|
|
|
@@ -1724,8 +2183,8 @@ semantics; it does not define a new storage protocol.
|
|
|
1724
2183
|
|
|
1725
2184
|
### Public surface
|
|
1726
2185
|
|
|
1727
|
-
Exact exports:
|
|
1728
|
-
`
|
|
2186
|
+
Exact exports: `PersistentAIChatSession`, `createPersistentAIChatSession`, and
|
|
2187
|
+
`default`.
|
|
1729
2188
|
|
|
1730
2189
|
Constructor and factory options are `{chat,chatEntity,chatFileName,
|
|
1731
2190
|
contextBuilder,loadExisting,maxContextCharacters,maxMessageCharacters,
|
|
@@ -1781,7 +2240,9 @@ Loads and updates schema-defined app preferences through native storage with a n
|
|
|
1781
2240
|
|
|
1782
2241
|
default `PreferenceStore`, re-exported `Preference`/schema; load/set/reset APIs and events.
|
|
1783
2242
|
|
|
1784
|
-
Exact exports: `
|
|
2243
|
+
Exact exports: `PREFERENCE_STORE_ERROR_CODES`,
|
|
2244
|
+
`PREFERENCE_STORE_EVENT_TYPES`, `Preference`, `default`, and
|
|
2245
|
+
`preferenceSchema`.
|
|
1785
2246
|
|
|
1786
2247
|
### Availability and normalization
|
|
1787
2248
|
|
|
@@ -1899,7 +2360,9 @@ Stores normalized record-review decisions through native storage or app-scoped l
|
|
|
1899
2360
|
|
|
1900
2361
|
default store, record/review normalizers; `load()`, `get()`, `set()`, `snapshot()`, change event.
|
|
1901
2362
|
|
|
1902
|
-
Exact exports: `
|
|
2363
|
+
Exact exports: `RECORD_REVIEW_STORE_ERROR_CODES`,
|
|
2364
|
+
`RECORD_REVIEW_STORE_EVENT_TYPES`, `default`, `normalizeRecordId`, and
|
|
2365
|
+
`normalizeReview`.
|
|
1903
2366
|
|
|
1904
2367
|
### Availability and normalization
|
|
1905
2368
|
|
|
@@ -2019,7 +2482,9 @@ Captures a display surface as image, video, or GIF with explicit lifecycle event
|
|
|
2019
2482
|
|
|
2020
2483
|
default `ScreenCapture`; acquire/capture/start/stop/reset methods.
|
|
2021
2484
|
|
|
2022
|
-
Exact exports: `
|
|
2485
|
+
Exact exports: `SCREEN_CAPTURE_ERROR_CODES`, `SCREEN_CAPTURE_ERRORS`,
|
|
2486
|
+
`SCREEN_CAPTURE_EVENT_TYPES`, `SCREEN_CAPTURE_IMAGE_TYPE_FALLBACK`,
|
|
2487
|
+
`SCREEN_CAPTURE_REASONS`, `SCREEN_CAPTURE_STATUSES`, and `default`.
|
|
2023
2488
|
|
|
2024
2489
|
### Availability and normalization
|
|
2025
2490
|
|
|
@@ -2041,13 +2506,75 @@ Segments bounded text, queues latest-request speech synthesis, and controls look
|
|
|
2041
2506
|
|
|
2042
2507
|
### Public surface
|
|
2043
2508
|
|
|
2044
|
-
SpeechPlayback class/default, voice/limit constants,
|
|
2509
|
+
`SpeechPlayback` class/default, voice/limit compatibility constants,
|
|
2510
|
+
`SPEECH_PLAYBACK_STATE_EVENT`, `splitSpeechText()`, and playback lifecycle APIs.
|
|
2045
2511
|
|
|
2046
|
-
Exact exports: `MAX_SPEECH_CHARACTERS`, `MAX_SPEECH_CHUNKS`,
|
|
2047
|
-
|
|
2048
|
-
|
|
2512
|
+
Exact exports: `MAX_SPEECH_CHARACTERS`, `MAX_SPEECH_CHUNKS`,
|
|
2513
|
+
`MAX_SPEECH_INPUT`, `PREFERRED_STREAM_SEGMENT`, `SPEECH_PLAYBACK_STATE_EVENT`,
|
|
2514
|
+
`SPEECH_VOICE_ALIASES`, `SPEECH_VOICE_OPTIONS`, `SpeechPlayback`, `default`,
|
|
2515
|
+
and `splitSpeechText`.
|
|
2049
2516
|
|
|
2050
|
-
|
|
2517
|
+
```text
|
|
2518
|
+
new SpeechPlayback({
|
|
2519
|
+
audio,
|
|
2520
|
+
speech=globalThis.Arcane?.speech,
|
|
2521
|
+
model=null,
|
|
2522
|
+
voice=null,
|
|
2523
|
+
responseFormat=null,
|
|
2524
|
+
speed=1,
|
|
2525
|
+
onState=()=>{},
|
|
2526
|
+
createObjectURL,
|
|
2527
|
+
revokeObjectURL,
|
|
2528
|
+
delay,
|
|
2529
|
+
messages={}
|
|
2530
|
+
})
|
|
2531
|
+
```
|
|
2532
|
+
|
|
2533
|
+
`speech` must expose either `fetchTTS(payload, signal)` or
|
|
2534
|
+
`synthesize(payload, {signal})`. `prepare({key,parts,model,voice,responseFormat,
|
|
2535
|
+
speed,autoplay=true})` uses only caller-supplied model, voice, and response-format
|
|
2536
|
+
values; those three omitted values remain omitted so the selected AI/model
|
|
2537
|
+
catalog may admit its documented defaults. Speed defaults to `1`, is normalized
|
|
2538
|
+
as a positive number, and is always sent. The legacy voice constants remain
|
|
2539
|
+
exported for compatibility but are not selected by the class. There is no
|
|
2540
|
+
hard-coded model, response format, voice, or cloud/browser fallback.
|
|
2541
|
+
|
|
2542
|
+
Every preparation owns an operation ID and one AbortController for each active
|
|
2543
|
+
synthesis segment or playback delay. Replacement,
|
|
2544
|
+
`stop()`, `cancel()`, and `destroy()` abort their owned signals, suppress stale
|
|
2545
|
+
settlement, release Blob URLs, and publish synchronous
|
|
2546
|
+
`speech-playback-state` occurrences through `globalThis.arcaneEvents` before
|
|
2547
|
+
calling the compatibility `onState(frozenDetail)` callback. The detail contains
|
|
2548
|
+
`state`, `message`, `key`, `index`, `total`, `producing`, `buffered`, `hasAudio`,
|
|
2549
|
+
`operationId`, `code`, and `reason`; the canonical public occurrence omits
|
|
2550
|
+
provider response/error bodies. `destroy()` also removes every audio listener
|
|
2551
|
+
and disposes its per-instance canonical source handle; repeated destroy returns
|
|
2552
|
+
`false`. Signal abortion proves delivery suppression; whether provider work
|
|
2553
|
+
actually stops remains the selected provider's cancellation boundary.
|
|
2554
|
+
|
|
2555
|
+
Stable error codes are `ARCANE_SPEECH_PLAYBACK_DESTROYED`,
|
|
2556
|
+
`ARCANE_SPEECH_PLAYBACK_OPERATION_SEQUENCE_EXHAUSTED`,
|
|
2557
|
+
`ARCANE_SPEECH_PLAYBACK_SYNTHESIZER_UNAVAILABLE`,
|
|
2558
|
+
`ARCANE_SPEECH_PLAYBACK_SYNTHESIZED_AUDIO_CONTRACT_MISMATCH`,
|
|
2559
|
+
`ARCANE_SPEECH_PLAYBACK_AUDIO_PLAYBACK_REJECTED`,
|
|
2560
|
+
`ARCANE_SPEECH_PLAYBACK_REQUEST_CONTRACT_MISMATCH`, and
|
|
2561
|
+
`ARCANE_SPEECH_PLAYBACK_SYNTHESIS_REQUEST_REJECTED`, plus propagated
|
|
2562
|
+
`ARCANE_AI_OPERATION_SUPERSEDED` and `ARCANE_AI_REQUEST_ABORTED`.
|
|
2563
|
+
Exact lifecycle reasons are `playback-replaced`, `playback-stopped`,
|
|
2564
|
+
`playback-destroyed`, `speech-playback-cancelled`,
|
|
2565
|
+
`speech-synthesis-superseded`, `speech-synthesis-cancelled`,
|
|
2566
|
+
`speech-synthesizer-unavailable`, `synthesized-audio-contract-mismatch`,
|
|
2567
|
+
`audio-playback-rejected`, `audio-autoplay-rejected`,
|
|
2568
|
+
`speech-playback-request-contract-mismatch`, and
|
|
2569
|
+
`speech-synthesis-rejected`, as applicable to the emitted state.
|
|
2570
|
+
|
|
2571
|
+
### Availability and normalization
|
|
2572
|
+
|
|
2573
|
+
**Browser + admitted AI/native bridge.** State, cancellation, lifecycle, and
|
|
2574
|
+
playable Blob normalization are shared. Provider/model/runtime/voice admission
|
|
2575
|
+
remains caller- and catalog-owned. Transport: `AI.fetchTTS`, compatible
|
|
2576
|
+
`Arcane.speech.synthesize`, Blob URLs, audio element, and the singleton event
|
|
2577
|
+
authority. [Deep protocol details](protocols.md).
|
|
2051
2578
|
|
|
2052
2579
|
### Example
|
|
2053
2580
|
|
|
@@ -2056,7 +2583,13 @@ import SpeechPlayback from '/arcane/modules/SpeechPlayback.js';
|
|
|
2056
2583
|
|
|
2057
2584
|
const audio = document.body.appendChild(document.createElement('audio'));
|
|
2058
2585
|
audio.controls = true;
|
|
2059
|
-
const speech = new SpeechPlayback({
|
|
2586
|
+
const speech = new SpeechPlayback({
|
|
2587
|
+
audio,
|
|
2588
|
+
speech: globalThis.ai,
|
|
2589
|
+
model: 'caller-selected-model',
|
|
2590
|
+
voice: 'caller-selected-voice',
|
|
2591
|
+
responseFormat: 'wav'
|
|
2592
|
+
});
|
|
2060
2593
|
const speakButton = document.body.appendChild(document.createElement('button'));
|
|
2061
2594
|
speakButton.type = 'button';
|
|
2062
2595
|
speakButton.textContent = 'Speak';
|
|
@@ -2173,7 +2706,8 @@ Maps native terminal sessions and Arcane events into an EventTarget client.
|
|
|
2173
2706
|
|
|
2174
2707
|
default `TerminalClient`; start/write/resize/signal/close/receive/destroy APIs and terminal events.
|
|
2175
2708
|
|
|
2176
|
-
Exact exports: `
|
|
2709
|
+
Exact exports: `TERMINAL_CLIENT_ERROR_CODES`, `TERMINAL_CLIENT_EVENT_TYPES`,
|
|
2710
|
+
`TERMINAL_CLIENT_REASONS`, and `default`.
|
|
2177
2711
|
|
|
2178
2712
|
### Availability and normalization
|
|
2179
2713
|
|
|
@@ -2221,7 +2755,8 @@ Performs import-time Arcane theme loading and subscribes to native appearance ch
|
|
|
2221
2755
|
|
|
2222
2756
|
`bootstrapArcaneTheme()`, `arcaneThemeReady`, default ready promise.
|
|
2223
2757
|
|
|
2224
|
-
Exact exports: `arcaneThemeReady`, `bootstrapArcaneTheme`, `default
|
|
2758
|
+
Exact exports: `arcaneThemeReady`, `bootstrapArcaneTheme`, `default`, and
|
|
2759
|
+
`disposeArcaneThemeBootstrap`.
|
|
2225
2760
|
|
|
2226
2761
|
### Availability and normalization
|
|
2227
2762
|
|
|
@@ -2379,7 +2914,8 @@ Waits for a component property, method, or readiness event with optional error e
|
|
|
2379
2914
|
|
|
2380
2915
|
default `waitForComponent()`.
|
|
2381
2916
|
|
|
2382
|
-
Exact exports: `
|
|
2917
|
+
Exact exports: `COMPONENT_WAIT_ERROR_CODES`, `COMPONENT_WAIT_REASONS`, and
|
|
2918
|
+
`default`.
|
|
2383
2919
|
|
|
2384
2920
|
### Availability and normalization
|
|
2385
2921
|
|