arcane-os 0.5.11 → 0.5.12
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 +22 -0
- package/README.md +8 -8
- package/docs/architecture.md +1 -1
- package/docs/reference/README.md +5 -5
- package/docs/reference/ai/browser-speech.md +73 -7
- package/docs/reference/ai/twin-cloud.md +1 -1
- package/docs/reference/cli.md +1 -1
- package/docs/reference/core/arcane-ai-contracts.md +2 -3
- package/docs/reference/core/arcane-api.md +5 -5
- package/docs/reference/core/ollama-module.md +1 -1
- package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +2 -2
- package/docs/reference/inventory/package-api.json +1 -1
- package/docs/reference/inventory/runtime-components.json +1 -1
- package/docs/reference/inventory/runtime-modules.json +3 -3
- package/docs/reference/protocols.md +5 -5
- package/docs/reference/runtime-components.md +5 -2
- package/docs/reference/runtime-modules.md +39 -4
- package/docs/reference/sdk-api.md +6 -6
- package/package.json +1 -1
- package/runtime/arcane/modules/AI.js +59 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.5.12
|
|
6
|
+
|
|
7
|
+
- Add optional `voice`, `speed`, `pauseAfterMs`, and `waitForPlayback` fields to
|
|
8
|
+
`AI.streamTTS(text, end, options)`. Complete passages can enter the existing
|
|
9
|
+
segmented generation queue immediately, retain their authored pauses on the
|
|
10
|
+
audio clock, and await their own playback completion. Existing calls still
|
|
11
|
+
return after preparation; stop and terminal failure settle playback waits
|
|
12
|
+
as `false`, while autoplay permission waiting remains pending.
|
|
13
|
+
- Restore `AI.fetch(...)` and `AI.streamMessage(...)` after their unintended
|
|
14
|
+
removal during source cleanup. Their existing signatures, callbacks, return
|
|
15
|
+
behavior, and private inference plumbing remain available alongside
|
|
16
|
+
`fetchRequest({...})` and `streamRequest({...})`; callers do not need to
|
|
17
|
+
migrate. Restore chat-memory callers and document both public forms as
|
|
18
|
+
sharing the current provider implementations.
|
|
19
|
+
- Update maintained SDK references and their generated pages, omit obsolete
|
|
20
|
+
provider context-token guidance, and describe current native defaults and
|
|
21
|
+
Winlogon bindings without treating them
|
|
22
|
+
as retired SDK APIs. Native Core implementations and upstream dependencies
|
|
23
|
+
are not changed by this SDK cleanup.
|
|
24
|
+
|
|
3
25
|
## 0.5.11
|
|
4
26
|
|
|
5
27
|
- Default browser Kokoro TTS to four concurrent synthesis slots in both the
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ version-locked SDK runtime, while an integrated Arcane checkout uses its live
|
|
|
19
19
|
`arcane/` runtime. Both profiles preserve the same app URLs, theme, packaging,
|
|
20
20
|
event, cancellation, and browser run contracts.
|
|
21
21
|
|
|
22
|
-
This checkout defines the `0.5.
|
|
22
|
+
This checkout defines the `0.5.12` SDK contract. Applications pin one exact npm
|
|
23
23
|
version and lockfile; registry state is deliberately not baked into application
|
|
24
24
|
artifacts.
|
|
25
25
|
|
|
@@ -35,7 +35,7 @@ Create one browser application, install its pinned SDK, and start its source
|
|
|
35
35
|
server:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
npx arcane-os@0.5.
|
|
38
|
+
npx arcane-os@0.5.12 new hello-speech --path ./hello-speech --target browser
|
|
39
39
|
cd hello-speech
|
|
40
40
|
npm install
|
|
41
41
|
npm run dev
|
|
@@ -297,7 +297,7 @@ uses the same controller for automatic memory extraction.
|
|
|
297
297
|
Create a new repository-shaped Arcane application with the exact stable SDK:
|
|
298
298
|
|
|
299
299
|
```bash
|
|
300
|
-
npx arcane-os@0.5.
|
|
300
|
+
npx arcane-os@0.5.12 new my-app --path ./my-app --target portable --git
|
|
301
301
|
cd my-app
|
|
302
302
|
npm install
|
|
303
303
|
npm run dev
|
|
@@ -307,7 +307,7 @@ To enroll an existing repository, install the exact SDK and initialize only
|
|
|
307
307
|
missing Arcane files:
|
|
308
308
|
|
|
309
309
|
```bash
|
|
310
|
-
npm install --save-dev --save-exact arcane-os@0.5.
|
|
310
|
+
npm install --save-dev --save-exact arcane-os@0.5.12
|
|
311
311
|
npm exec -- arcane init my-app --target portable
|
|
312
312
|
```
|
|
313
313
|
|
|
@@ -323,7 +323,7 @@ npm exec -- arcane-os targets
|
|
|
323
323
|
No global SDK install or standalone Arcane CLI is required. The application
|
|
324
324
|
repository's exact npm dependency and lockfile own the CLI and toolchain version.
|
|
325
325
|
|
|
326
|
-
Use `npx arcane-os@0.5.
|
|
326
|
+
Use `npx arcane-os@0.5.12` for the initial bootstrap because it names this npm
|
|
327
327
|
package explicitly; bare `npx arcane` outside an installed project could resolve
|
|
328
328
|
a different package. Both installed commands invoke the same headless toolchain.
|
|
329
329
|
Project-local npm scripts use the SDK pinned by that app's `package-lock.json`,
|
|
@@ -343,7 +343,7 @@ node ./bin/arcane.mjs new local-app --path ../local-app --target portable --git
|
|
|
343
343
|
|
|
344
344
|
# From the generated app repository
|
|
345
345
|
cd ../local-app
|
|
346
|
-
npm install --save-dev --save-exact ../arcane-os-sdk/arcane-os-0.5.
|
|
346
|
+
npm install --save-dev --save-exact ../arcane-os-sdk/arcane-os-0.5.12.tgz
|
|
347
347
|
npm ci
|
|
348
348
|
```
|
|
349
349
|
|
|
@@ -352,7 +352,7 @@ same location. The lockfile retains the selected package dependency while
|
|
|
352
352
|
Arcane uses the installed package name and version. Local directory `file:` dependencies are not
|
|
353
353
|
accepted because npm may install them as links; use a packed `.tgz`. A GitHub
|
|
354
354
|
runner also needs that tarball at the locked path. After publication, replace
|
|
355
|
-
the local declaration with the exact `arcane-os@0.5.
|
|
355
|
+
the local declaration with the exact `arcane-os@0.5.12` registry package and
|
|
356
356
|
commit the regenerated lock.
|
|
357
357
|
|
|
358
358
|
Generated repositories use `npm ci --ignore-scripts` in CI. Run dependency
|
|
@@ -491,7 +491,7 @@ package installation, or assertions.
|
|
|
491
491
|
|
|
492
492
|
## Current target support
|
|
493
493
|
|
|
494
|
-
Version `0.5.
|
|
494
|
+
Version `0.5.12` exposes one browser target and five explicitly paired
|
|
495
495
|
native development targets: a non-runnable portable directory, a
|
|
496
496
|
Windows x64 unsigned-local-test EXE bundle, Linux x64 and Linux ARM64
|
|
497
497
|
unsigned-local-test DEBs, and an Android development-signed APK. The
|
package/docs/architecture.md
CHANGED
|
@@ -279,7 +279,7 @@ paths are withheld from the native provider. The provider copies the complete
|
|
|
279
279
|
selected release rather than accepting an unrelated source path. Verification
|
|
280
280
|
is a separate explicit operation for a selected release artifact.
|
|
281
281
|
|
|
282
|
-
The SDK `0.5.
|
|
282
|
+
The SDK `0.5.12` runtime requires Arcane `0.8.12` or newer. Compatibility
|
|
283
283
|
is contractual rather than exact-version pinning: the prepared Core must meet
|
|
284
284
|
the highest minimum declared by the runtime, selected app, and bundled app
|
|
285
285
|
dependencies; keep each app's Arcane protocol generation; and provide every
|
package/docs/reference/README.md
CHANGED
|
@@ -17,7 +17,7 @@ high-level page links to the relevant deep section instead of repeating it.
|
|
|
17
17
|
Install the SDK in your application:
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
npm install --save-exact arcane-os@0.5.
|
|
20
|
+
npm install --save-exact arcane-os@0.5.12
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
For your first AI call, follow the [TWiN Cloud quick start](ai/twin-cloud.md).
|
|
@@ -56,9 +56,9 @@ This repository contains explicitly versioned surfaces with different owners:
|
|
|
56
56
|
|
|
57
57
|
| Surface | Source identity | Meaning |
|
|
58
58
|
| --- | --- | --- |
|
|
59
|
-
| SDK and CLI | `arcane-os` `0.5.
|
|
60
|
-
| Browser runtime | SDK `0.5.
|
|
61
|
-
| Browser SDK runtime | SDK `0.5.
|
|
59
|
+
| SDK and CLI | `arcane-os` `0.5.12` | The Node.js toolchain, portable `arcane-os/event-manager`, `arcane-os/mail`, `arcane-os/preference-store`, and `arcane-os/speech-playback` entrypoints, plus the browser-only `arcane-os/ai/browser-wasm` and `arcane-os/ai/browser-speech` entrypoints in this checkout. |
|
|
60
|
+
| Browser runtime | SDK `0.5.12`, protocol `arcane/1`, `runtime/` | The SDK-canonical runtime tree. `listRuntimeFiles()`, `readRuntimeFile()`, and `loadRuntimeRelease()` derive its current inventory directly from the selected directory. |
|
|
61
|
+
| Browser SDK runtime | SDK `0.5.12`, `browser-runtime/` | The browser closure for events, Wllama, and Browser Speech mechanisms. `listSdkBrowserRuntimeFiles()`, `readSdkBrowserRuntimeFile()`, and `loadSdkBrowserRuntimeRelease()` derive its current inventory directly from the selected directory. |
|
|
62
62
|
| Core reference snapshot | Arcane OS commit `567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e`, protocol `arcane/1` | The application-facing Core contract imported into `docs/reference/core/`, with SDK-local links and package-boundary notes added explicitly. |
|
|
63
63
|
|
|
64
64
|
The SDK runtime source and Core reference have different owners. A browser
|
|
@@ -73,7 +73,7 @@ and the distinction between a documentation snapshot and the selected runtime.
|
|
|
73
73
|
|
|
74
74
|
## Installed documentation and release identity
|
|
75
75
|
|
|
76
|
-
This reference accompanies `arcane-os@0.5.
|
|
76
|
+
This reference accompanies `arcane-os@0.5.12`. The installed package includes
|
|
77
77
|
the maintained `docs/` tree and `examples/wasm-ai-demo/` source alongside
|
|
78
78
|
README and CHANGELOG. Open `node_modules/arcane-os/docs/reference/README.md`
|
|
79
79
|
for the matching local reference. The generated website and test suites remain
|
|
@@ -13,7 +13,7 @@ import map resolves `arcane/AI` and `arcane/DBOPFS`. These browser modules are
|
|
|
13
13
|
not Node inference APIs. To create an application:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npx arcane-os@0.5.
|
|
16
|
+
npx arcane-os@0.5.12 new hello-speech --path ./hello-speech --target browser
|
|
17
17
|
cd hello-speech
|
|
18
18
|
npm install
|
|
19
19
|
npm run dev
|
|
@@ -89,8 +89,8 @@ speakButton.addEventListener('click', async function sayHello() {
|
|
|
89
89
|
speakButton.disabled = true;
|
|
90
90
|
try {
|
|
91
91
|
await ai.setSpeechMuted(false); // Loads the selected TTS provider.
|
|
92
|
-
const
|
|
93
|
-
console.log('Speech preparation completed:',
|
|
92
|
+
const prepared = await ai.streamTTS('Hello from Arcane. ', true);
|
|
93
|
+
console.log('Speech preparation completed:', prepared);
|
|
94
94
|
} catch (error) {
|
|
95
95
|
console.error(error.code, error.message);
|
|
96
96
|
} finally {
|
|
@@ -101,10 +101,12 @@ speakButton.addEventListener('click', async function sayHello() {
|
|
|
101
101
|
|
|
102
102
|
The first user action may download the selected runtime, model, and voice.
|
|
103
103
|
The browser may require another audio-unlock gesture after a long load; the SDK
|
|
104
|
-
retains prepared audio for that gesture. `streamTTS()`
|
|
105
|
-
|
|
106
|
-
`false`
|
|
107
|
-
|
|
104
|
+
retains prepared audio for that gesture. The two-argument `streamTTS()` call
|
|
105
|
+
resolves after preparing audio for scheduling; it does not wait for playback
|
|
106
|
+
to end. It returns `false` when that preparation is muted, stopped, or fails.
|
|
107
|
+
Later playback failures still reach the SDK's complete console diagnostics
|
|
108
|
+
and `ai-tts-failure` event. Use the optional playback mode below when you need
|
|
109
|
+
to wait for the submitted audio to end. Neither mode proves a listener heard it.
|
|
108
110
|
|
|
109
111
|
To display complete high-level playback errors in this page, observe its
|
|
110
112
|
existing event. The listener belongs to this example's one `ai` instance:
|
|
@@ -133,6 +135,70 @@ Ready adjacent audio buffers use contiguous AudioContext scheduling. Browser
|
|
|
133
135
|
audio scheduling and selected WebGPU status do not prove physical GPU kernel
|
|
134
136
|
overlap or audio quality. LLM and Whisper/STT capacity remains one.
|
|
135
137
|
|
|
138
|
+
## Queue complete passages and wait for playback
|
|
139
|
+
|
|
140
|
+
These options are available in SDK `0.5.12`.
|
|
141
|
+
|
|
142
|
+
For a complete page or passage, call
|
|
143
|
+
`ai.streamTTS(text, true, {voice, speed, pauseAfterMs, waitForPlayback:true})`.
|
|
144
|
+
The existing AI queue owns segmentation, concurrent synthesis, ordered
|
|
145
|
+
playback, and cancellation. Supply the exact text; there is no need for an
|
|
146
|
+
application sentence queue, audio cache, or playback scheduler.
|
|
147
|
+
|
|
148
|
+
This function uses the configured `ai` above. Its application-supplied
|
|
149
|
+
`passages` argument is an ordered array of `{text, voice?, speed?, pauseAfterMs?}`
|
|
150
|
+
records. An omitted voice uses the selected model's default voice, an omitted
|
|
151
|
+
speed uses `ai.voiceSpeed`, and an omitted pause is zero. Each supplied voice
|
|
152
|
+
must be supported by the selected model; speed must be positive. A pause is
|
|
153
|
+
finite, nonnegative milliseconds and applies only after that passage's final
|
|
154
|
+
extracted segment. These options do not change the instance defaults.
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
async function speakPassages(passages) {
|
|
158
|
+
await ai.setSpeechMuted(false);
|
|
159
|
+
const pending = passages.map(
|
|
160
|
+
function queuePassage(passage) {
|
|
161
|
+
return ai.streamTTS(
|
|
162
|
+
passage.text,
|
|
163
|
+
true,
|
|
164
|
+
{
|
|
165
|
+
voice: passage.voice,
|
|
166
|
+
speed: passage.speed,
|
|
167
|
+
pauseAfterMs: passage.pauseAfterMs,
|
|
168
|
+
waitForPlayback: true
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
return Promise.all(pending);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Call `speakPassages(...)` from your owned user action and handle errors with
|
|
178
|
+
the earlier `error.code` / `error.message` pattern. The `map` submits every
|
|
179
|
+
passage synchronously before `Promise.all` waits, so synthesis can use the
|
|
180
|
+
provider's available capacity. The returned array has one boolean per passage
|
|
181
|
+
in input order: `true` after all its extracted audio buffers naturally end,
|
|
182
|
+
or `false` after terminal cancellation or failure. `ai.stopAudio()` cancels
|
|
183
|
+
all speech owned by that AI instance and settles pending playback results
|
|
184
|
+
`false`.
|
|
185
|
+
|
|
186
|
+
The selected voice and speed are captured for segments extracted by that call.
|
|
187
|
+
That includes any text left in the same AI instance's partial-stream buffer;
|
|
188
|
+
finish the previous producer before starting a separate complete passage.
|
|
189
|
+
Options are not retained with an unfinished `end:false` remainder. A later
|
|
190
|
+
call supplies its own options, and `finishTTS()` uses defaults.
|
|
191
|
+
A call extracting no segments returns `true` without waiting for earlier jobs.
|
|
192
|
+
An already muted call returns `false`.
|
|
193
|
+
|
|
194
|
+
Autoplay permission waiting and recoverable audio-resume attempts leave the
|
|
195
|
+
playback promise pending until playback completes or is stopped. A failed
|
|
196
|
+
resume of a closed `AudioContext` terminates the affected jobs and settles
|
|
197
|
+
their playback results `false`. A trailing
|
|
198
|
+
pause delays the next queued audio on the existing `AudioContext` clock; it
|
|
199
|
+
does not delay the preceding promise after that passage's last buffer ends.
|
|
200
|
+
The promise is a playback result, not a listener acknowledgement.
|
|
201
|
+
|
|
136
202
|
## Stream chunks as they arrive
|
|
137
203
|
|
|
138
204
|
Use the configured `ai` created above. Run this snippet from an owned user
|
|
@@ -9,7 +9,7 @@ same managed browser imports as the [browser speech quick start](browser-speech.
|
|
|
9
9
|
Create an application and start its source server:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx arcane-os@0.5.
|
|
12
|
+
npx arcane-os@0.5.12 new hello-twin --path ./hello-twin --target browser
|
|
13
13
|
cd hello-twin
|
|
14
14
|
npm install
|
|
15
15
|
npm run dev
|
package/docs/reference/cli.md
CHANGED
|
@@ -214,7 +214,7 @@ portable runtime subpaths such as `arcane-os/preference-store` and
|
|
|
214
214
|
modules. The result reports the complete map written to the selected
|
|
215
215
|
application; no fixed entry count is a release contract.
|
|
216
216
|
|
|
217
|
-
SDK `0.5.
|
|
217
|
+
SDK `0.5.12` preserves the physical workspace route count and ordered include
|
|
218
218
|
list. External and modern integrated routes require `components`, `css`,
|
|
219
219
|
`dependencies`, `entities`, `img`, `modules`, and `sdk`; a physical workspace
|
|
220
220
|
may omit only an optional trailing `security` include. The external license
|
|
@@ -9,7 +9,7 @@ They are not TypeScript declarations.
|
|
|
9
9
|
|
|
10
10
|
## Portable SDK AI and Core AI
|
|
11
11
|
|
|
12
|
-
The SDK `0.5.
|
|
12
|
+
The SDK `0.5.12` has two related but separate normalized boundaries:
|
|
13
13
|
|
|
14
14
|
| Boundary | Use | Host |
|
|
15
15
|
|---|---|---|
|
|
@@ -132,7 +132,7 @@ No other message fields are accepted.
|
|
|
132
132
|
| `model` | `string` | Yes | Effective configured model | Model used by provider-neutral chat. |
|
|
133
133
|
| `configured` | `boolean` | Yes | - | Required provider configuration is present. |
|
|
134
134
|
| `local` | `boolean` | Yes | `true` only for Ollama | Whether inference remains local. |
|
|
135
|
-
| `responseLength` | `"low" \| "medium" \| "high"` | Yes |
|
|
135
|
+
| `responseLength` | `"low" \| "medium" \| "high"` | Yes | Invalid/missing state resolves to `"medium"` | Conversational response target, not a provider token limit. |
|
|
136
136
|
|
|
137
137
|
An OpenAI profile is returned only after Arcane proves a protected credential
|
|
138
138
|
exists and the configured model is available to that account.
|
|
@@ -620,7 +620,6 @@ The wrapper supplies the validated `model` field.
|
|
|
620
620
|
| `format` | JSON value | No | Text, JSON, or schema format | Output format. |
|
|
621
621
|
| `options` | object | No | Provider-native; `num_ctx` is 1,024-262,144 when supplied | Runtime options. |
|
|
622
622
|
| `system`, `template` | `string` | No | Provider-native | Prompt controls. |
|
|
623
|
-
| `context` | `array` | No | Provider-native | Legacy context tokens. |
|
|
624
623
|
| `raw` | `boolean` | No | Provider-native | Raw prompt mode. |
|
|
625
624
|
| `keep_alive` | `string \| number` | No | Provider-native | Residency. |
|
|
626
625
|
| `think`, `logprobs`, `top_logprobs` | JSON value | No | Provider-native | Reasoning/log-probability controls. |
|
|
@@ -128,7 +128,7 @@ directly.
|
|
|
128
128
|
| `Arcane.ollama.saveServiceSettings(settings)` | `settings`: [`OllamaServiceSettingsInput`](arcane-ai-contracts.md#ollama-service-settings-input) | [`Promise<OllamaServiceSettingsResult>`](arcane-ai-contracts.md#ollama-service-settings-result) | Saves managed service settings. |
|
|
129
129
|
|
|
130
130
|
The native AI profile always returns `responseLength` as `"low"`, `"medium"`,
|
|
131
|
-
or `"high"`; missing or invalid
|
|
131
|
+
or `"high"`; missing or invalid persisted values safely resolve to
|
|
132
132
|
`"medium"`. New saves reject any other value. Conversational applications may
|
|
133
133
|
use this target to augment their system prompt, but specific user requests and
|
|
134
134
|
required application, structured-output, tool, safety, evidence, warning, or
|
|
@@ -537,9 +537,9 @@ exclusive-mutation boundary. Native set results must match the requested name,
|
|
|
537
537
|
protection decision, and exact ordinary value or protected five-bullet mask
|
|
538
538
|
before Core returns them.
|
|
539
539
|
Microsoft NT rejects a protected-record/plaintext-registry shadow. Linux binds
|
|
540
|
-
new protected values to a random Secret Service generation
|
|
541
|
-
|
|
542
|
-
|
|
540
|
+
new protected values to a random Secret Service generation and fsyncs the
|
|
541
|
+
metadata file and directory before cleaning the prior generation. Native
|
|
542
|
+
storage implementation details belong to Arcane Core, not the SDK.
|
|
543
543
|
Failure to verify candidate, prior-generation, or deletion cleanup rejects with
|
|
544
544
|
`ENVIRONMENT_PROTECTED_CLEANUP_FAILED`. Linux post-rename durability ambiguity
|
|
545
545
|
rejects with `ENVIRONMENT_METADATA_COMMIT_UNCERTAIN`. Native code retains
|
|
@@ -579,7 +579,7 @@ Native storage and preferences resolve below
|
|
|
579
579
|
cannot provide a different identity. Browser OPFS follows
|
|
580
580
|
`apps/<application-id>/...`, DBLS fallback keys use
|
|
581
581
|
`arcane.apps.<application-id>:`, and native browser profiles are also app-owned.
|
|
582
|
-
Unowned
|
|
582
|
+
Unowned global data is preserved but not guessed into an app. The complete
|
|
583
583
|
layout and same-origin browser limitation are maintained in the repository-only
|
|
584
584
|
[Application data isolation](https://github.com/TheWizardNexus/ARCANE-OS/blob/567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e/docs/application-data-isolation.md); see the public [repository-access boundary](https://github.com/TheWizardNexus/ARCANE-OS/blob/567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e/apps/docs/guides/repository-access.md#private-developer-material).
|
|
585
585
|
|
|
@@ -82,7 +82,7 @@ The service is configured with the global `OLLAMA_MODELS` directory. Arcane clie
|
|
|
82
82
|
npm run model:ensure -- --target=all --model=3b --smoke
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
`--target=arcane`
|
|
85
|
+
`--target=arcane` selects the platform model and is the default. Product-specific targets and definitions remain documented by their owning applications. `--target=all` reuses one base pull across both currently configured targets, selects `arcane:3b` as `arcane:latest`, and preserves unrelated settings. `--smoke` adds one bounded local inference probe per selected alias. The equivalent platform-only raw Ollama sequence is `ollama pull granite4.1:3b-q4_K_M` followed by `ollama create arcane:3b -f arcane/models/Arcane-3B.Modelfile`; the npm command additionally verifies lineage and is the supported repository workflow.
|
|
86
86
|
|
|
87
87
|
The managed service's aliases and model layers are machine-wide, while Arcane model preference and application profile selection remain per-user. `model:ensure` does not install or attest `ArcaneOllama`, does not update an already installed Core or UI after a source pull, and does not create application aliases outside the selected target set. Use the verified Provisioner to establish or repair the machine service and to install current application/runtime bytes. The public [Device and model support](https://github.com/TheWizardNexus/ARCANE-OS/blob/567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e/apps/docs/guides/device-support.md) page tracks the exact product matrix, platform maturity, and COTS physical-validation backlog; 16B and 30B are validation targets, not managed variants.
|
|
88
88
|
|
|
@@ -516,7 +516,7 @@ recorded binding/security metadata, `canRestoreShell`,
|
|
|
516
516
|
`shellRecoveryPrepared`, `accountMutationPhase`, and `activationRequired`.
|
|
517
517
|
|
|
518
518
|
Microsoft NT records include `username`, `sid`, `enabled`, `profile`, `shell`,
|
|
519
|
-
both policy and
|
|
519
|
+
both policy and Winlogon shell values/presence flags, `shellAssigned`,
|
|
520
520
|
`shellBindingVersion`, `assignmentMode`, `verification`, and `source`. Linux
|
|
521
521
|
records include `username`, optional `uid`, `enabled`, `profile`, `shell`,
|
|
522
522
|
`shellAssigned`, `verification`, and `source`. Nullable or recorded-only values
|
|
@@ -824,7 +824,7 @@ Provisioner type, elevation, and the exclusive Core mutation boundary. It does
|
|
|
824
824
|
not delete the account or change its password, but it materially changes what
|
|
825
825
|
starts at the user's next sign-in.
|
|
826
826
|
|
|
827
|
-
Microsoft NT restores both prior policy and
|
|
827
|
+
Microsoft NT restores both prior policy and Winlogon shell bindings, including
|
|
828
828
|
their recorded absence. Linux restores the recorded login shell after checking
|
|
829
829
|
the exact uid and ensuring the prior executable still exists. The host refuses
|
|
830
830
|
to overwrite a value changed outside the recorded transaction.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"repository": "https://github.com/TheWizardNexus/arcane-os-sdk.git",
|
|
6
6
|
"branch": "main",
|
|
7
7
|
"path": "runtime/arcane",
|
|
8
|
-
"sdkVersion": "0.5.
|
|
8
|
+
"sdkVersion": "0.5.12",
|
|
9
9
|
"protocol": "arcane/1"
|
|
10
10
|
},
|
|
11
11
|
"artifactCount": 84,
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"summary": "Owns provider-selectable chat and the one-time caller-authority browser STT/TTS configuration, lifecycle, synthesis, transcription, and playback boundary.",
|
|
30
30
|
"availability": "Browser + native bridge + TWiN Cloud",
|
|
31
31
|
"protocol": "arcane-ai-browser-speech-configuration/1, AIProviderRuntime arcane-ai-provider/2 routes, globalThis.arcaneEvents, TWiN Cloud HTTPS, Arcane.ollama, Arcane.speech, Android WebView bridge",
|
|
32
|
-
"normalization": "Complete mutable caller-owned browser speech authority, SDK-owned provider registration/replacement/disposal, explicit STT/TTS activation, normalized Kokoro TTS execution with default capacity 4, explicit provider-neutral execution snapshots through status(role,{execution:true}), sticky readiness, canonical window.user readiness without compatibility-event object-identity admission or polling, exact ordered structural calls with required arguments.message, atomic nonblank all-ID tool-result sequencing, complete all-choice streaming/data validation, native Ollama structural adaptation, complete-response then all validated tool callbacks then completion ordering, observed async callbacks, Blob/File transcription, immediate exact-segment synthesis, ordered audio-clock scheduling, playable audio, active-generation TTS operation-failure routing, mute, and cancellation are normalized; provider/model/runtime/voice policy remains caller-owned.",
|
|
33
|
-
"surface": "Browser-speech protocol/event/error/reason constants; default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and `browserSpeechDescriptor`; explicit `providerRuntime.status(role,{execution:true})` snapshots; configure/dispose speech, route lifecycle, declaration-validated chat/stream requests with exact ordered calls, synthesis/transcription, and playback controls; initializes from current canonical user readiness, installs `window.ai`, and projects `ai-ready` plus active-generation `ai-tts-failure`."
|
|
32
|
+
"normalization": "Complete mutable caller-owned browser speech authority, SDK-owned provider registration/replacement/disposal, explicit STT/TTS activation, normalized Kokoro TTS execution with default capacity 4, explicit provider-neutral execution snapshots through status(role,{execution:true}), sticky readiness, canonical window.user readiness without compatibility-event object-identity admission or polling, exact ordered structural calls with required arguments.message, atomic nonblank all-ID tool-result sequencing, complete all-choice streaming/data validation, native Ollama structural adaptation, complete-response then all validated tool callbacks then completion ordering, observed async callbacks, Blob/File transcription, immediate exact-segment synthesis, per-call voice/speed capture, optional final-segment pause on the existing audio clock, optional per-call terminal playback completion, ordered audio-clock scheduling, playable audio, active-generation TTS operation-failure routing, mute, and cancellation are normalized; provider/model/runtime/voice policy remains caller-owned.",
|
|
33
|
+
"surface": "Browser-speech protocol/event/error/reason constants; default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and `browserSpeechDescriptor`; explicit `providerRuntime.status(role,{execution:true})` snapshots; `streamTTS(text,end,options={})` with optional voice, speed, pauseAfterMs, and waitForPlayback (available in SDK 0.5.12); configure/dispose speech, route lifecycle, declaration-validated chat/stream requests with exact ordered calls, synthesis/transcription, and playback controls; initializes from current canonical user readiness, installs `window.ai`, and projects `ai-ready` plus active-generation `ai-tts-failure`."
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
"file": "runtime/arcane/modules/AIPreferenceRuntime.js",
|
|
@@ -159,7 +159,7 @@ imports such as:
|
|
|
159
159
|
import ollama from 'arcane/Ollama';
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
The physical-v1 tree lives entirely beneath `arcane/`. SDK `0.5.
|
|
162
|
+
The physical-v1 tree lives entirely beneath `arcane/`. SDK `0.5.12` projects the
|
|
163
163
|
complete canonical runtime and browser runtime selected by the installed SDK
|
|
164
164
|
package. Runtime dependencies stay under
|
|
165
165
|
`arcane/dependencies/`; the SDK event and browser-AI closure stays under
|
|
@@ -174,7 +174,7 @@ integrated physical route uses the same ordered include list in its one route.
|
|
|
174
174
|
Omitting only that final optional entry is compatible. Removing, reordering, or
|
|
175
175
|
renaming any preceding entry changes the physical contract.
|
|
176
176
|
|
|
177
|
-
The `0.5.
|
|
177
|
+
The `0.5.12` map derives its complete entries from the selected runtime graph;
|
|
178
178
|
application source imports do not select a fixed entry count. The operation
|
|
179
179
|
result reports `imports`, `entryCount`, and `excludedModules`; reached-file
|
|
180
180
|
traversal remains internal. The
|
|
@@ -239,8 +239,8 @@ exactly `dependencyName`, `packageSource`,
|
|
|
239
239
|
`canonicalPackageRoot`, `packageName`, `packageVersion`, `runtimeRoot`,
|
|
240
240
|
and `browserRuntimeRoot`. A
|
|
241
241
|
workspace may use the canonical dependency name or one exact npm alias such as
|
|
242
|
-
`npm:arcane-os@0.5.
|
|
243
|
-
exactly as `arcane-os@0.5.
|
|
242
|
+
`npm:arcane-os@0.5.12`; the physical package manifest must still identify
|
|
243
|
+
exactly as `arcane-os@0.5.12`. Canonical-plus-alias duplicates, multiple aliases,
|
|
244
244
|
links/junctions, indirect package roots, or version drift are reported.
|
|
245
245
|
|
|
246
246
|
For external workspaces, `arcane dev` serves the projected `arcane/` root,
|
|
@@ -351,7 +351,7 @@ does not silently delete the app-owned cache. A complete whole member supersedes
|
|
|
351
351
|
its current resumable fragments. Cleanup failure is warned without hiding the
|
|
352
352
|
usable model.
|
|
353
353
|
|
|
354
|
-
SDK `0.5.
|
|
354
|
+
SDK `0.5.12` requires WebGPU. Load requests full offload and waits for the runtime
|
|
355
355
|
to report a loaded model. `navigator.gpu` presence alone is
|
|
356
356
|
not readiness. There is no CPU fallback, partial-offload success mode, or
|
|
357
357
|
silent switch to native/Core/cloud inference.
|
|
@@ -359,8 +359,11 @@ unload.
|
|
|
359
359
|
|
|
360
360
|
Chat listens for the bound (or current global) AI runtime's `ai-tts-failure`
|
|
361
361
|
event and forwards its complete Error and exact operation boundary to
|
|
362
|
-
`speech.reportTTSError()`.
|
|
363
|
-
|
|
362
|
+
`speech.reportTTSError()`. Playback-start or playback-resume failures can occur
|
|
363
|
+
after Chat's two-argument `streamTTS()` preparation promise has resolved.
|
|
364
|
+
SDK `0.5.12` adds a `waitForPlayback:true` mode for the
|
|
365
|
+
terminal result of the segments submitted by one invocation; Chat continues
|
|
366
|
+
to feed chunks without waiting for playback. Runtime mute, cancellation,
|
|
364
367
|
permission waiting, and stale generations remain non-errors.
|
|
365
368
|
|
|
366
369
|
Each visible model chunk is still forwarded to `AI.streamTTS()` in arrival
|
|
@@ -141,11 +141,17 @@ default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and
|
|
|
141
141
|
`configureSpeechProviders()`, `transitionAI()`, `transitionProviders()`,
|
|
142
142
|
`transitionSpeechProviders()`, `startProviders()`, `setSpeechMuted()`,
|
|
143
143
|
`streamRequest()`, `streamMessage()`, `fetchRequest()`, `fetch()`,
|
|
144
|
-
read-only `ttsSegmentation`, `configureTTSSegmentation()`,
|
|
144
|
+
read-only `ttsSegmentation`, `configureTTSSegmentation()`,
|
|
145
|
+
`streamTTS(text='',end=false,options={})`,
|
|
145
146
|
`finishTTS()`, `fetchTTS()`, `fetchSTT()`, `stopAudio()`, `resumeAudio()`,
|
|
146
147
|
`playAudio()`; consumes `user-entity-loaded` and `arcane-ollama-ready`,
|
|
147
148
|
installs `window.ai`, and emits `ai-ready` and `ai-tts-failure`.
|
|
148
149
|
|
|
150
|
+
`fetch(...)` and `fetchRequest(options)` are asynchronous complete-response
|
|
151
|
+
entry points. `streamMessage(...)` and `streamRequest(options)` deliver
|
|
152
|
+
incremental responses. The positional and object forms share the existing
|
|
153
|
+
provider implementations; neither form is a retired compatibility API.
|
|
154
|
+
|
|
149
155
|
Initialization uses the canonical realm user's actual readiness state. If
|
|
150
156
|
`window.user?.ready` is already true, AI initializes immediately. Otherwise one
|
|
151
157
|
shared registration observes `user-entity-loaded`, then rechecks readiness
|
|
@@ -248,8 +254,37 @@ the setting is the instance's `opus` default and the model rejects it, the catal
|
|
|
248
254
|
`speech.defaultResponseFormat` is used, while any other unsupported setting is
|
|
249
255
|
rejected. It propagates the caller-owned signal and returns a playable `Blob`;
|
|
250
256
|
it does not independently choose a provider, cloud fallback, model, runtime, or
|
|
251
|
-
voice policy for the application.
|
|
252
|
-
this same request boundary.
|
|
257
|
+
voice policy for the application. `streamTTS(text='',end=false,options={})` and
|
|
258
|
+
`finishTTS()` use this same request boundary. The third-argument options below
|
|
259
|
+
are available in SDK `0.5.12`:
|
|
260
|
+
|
|
261
|
+
| Field | Default | Meaning |
|
|
262
|
+
| --- | --- | --- |
|
|
263
|
+
| `voice` | Current selected model's default voice | A supplied voice is captured for every segment extracted by this call and forwarded unchanged to `fetchTTS()`. It does not change the instance or provider default. |
|
|
264
|
+
| `speed` | Current `ai.voiceSpeed` | A supplied positive speed is captured for those segments and forwarded to `fetchTTS()`. It does not change `ai.voiceSpeed`. |
|
|
265
|
+
| `pauseAfterMs` | `0` | Finite, nonnegative milliseconds placed after the final extracted segment on the existing audio clock. Invalid values throw `RangeError`; no pause is inserted between this call's other segments. |
|
|
266
|
+
| `waitForPlayback` | `false` | Omission retains the preparation promise. With `true`, the promise resolves after every extracted segment reaches a terminal playback state: `true` when all naturally end, or `false` after terminal cancellation or failure. |
|
|
267
|
+
|
|
268
|
+
The voice and speed use the existing `fetchTTS()` validation and error path.
|
|
269
|
+
No option rewrites the submitted text. Overrides belong to the segments
|
|
270
|
+
extracted in that invocation, including any text buffered by an earlier call.
|
|
271
|
+
Options are not retained with an unfinished `end:false` remainder; a later
|
|
272
|
+
call supplies its own options, and `finishTTS()` uses defaults. Use `end:true`
|
|
273
|
+
for a complete passage. A call extracting no segments resolves
|
|
274
|
+
`true` without waiting for earlier jobs; `finishTTS()` remains a preparation
|
|
275
|
+
flush, not a queue-wide playback barrier. A muted call resolves `false`.
|
|
276
|
+
|
|
277
|
+
Playback completion stays pending while the browser waits for an audio-unlock
|
|
278
|
+
gesture or a recoverable resume attempt. If resuming a closed `AudioContext`
|
|
279
|
+
fails, the affected jobs terminate and their playback results settle `false`.
|
|
280
|
+
`stopAudio()` cancels all speech owned
|
|
281
|
+
by this AI instance and settles pending playback promises `false`. A trailing
|
|
282
|
+
pause delays the next queued audio; the preceding promise resolves when its
|
|
283
|
+
last audio buffer ends, without waiting out that pause. Completion describes
|
|
284
|
+
the playback lifecycle, not proof that a listener heard the sound. See the
|
|
285
|
+
[complete-passage example](ai/browser-speech.md#queue-complete-passages-and-wait-for-playback).
|
|
286
|
+
|
|
287
|
+
Streaming speech retains sentence
|
|
253
288
|
segmentation by default. `configureTTSSegmentation({punctuation,wordCadence})`
|
|
254
289
|
accepts `punctuation:'sentence'|'any'|'none'` and a `wordCadence` that is either
|
|
255
290
|
`null` or a positive integer. `punctuation:'any'` completes a segment at a
|
|
@@ -1661,7 +1696,7 @@ and `read`, filters source metadata before calling
|
|
|
1661
1696
|
**Browser or compatible host with an injected DBOPFS adapter.** The adapter
|
|
1662
1697
|
keeps the existing `get`, `set`, `getAllKeys`, and `delete` method names; Node
|
|
1663
1698
|
can use the same class only through an explicitly imported runtime module and a
|
|
1664
|
-
compatible storage adapter; SDK `0.5.
|
|
1699
|
+
compatible storage adapter; SDK `0.5.12` publishes no Node package subpath or
|
|
1665
1700
|
Node storage implementation for it. Bootstrap uses a concurrent
|
|
1666
1701
|
generation, commits its manifest last, cleans partial data on failure, and
|
|
1667
1702
|
rejects case-colliding IDs. Search
|
|
@@ -18,7 +18,7 @@ This table is the Node `package.json#exports` map: it defines package
|
|
|
18
18
|
entrypoints for SDK/tooling code. It is distinct from the generated browser
|
|
19
19
|
import map that resolves application-facing `arcane/*` modules and the focused
|
|
20
20
|
EventManager entry. See [browser runtime delivery](protocols.md#browser-runtime-delivery)
|
|
21
|
-
for the installed-inventory-derived physical-runtime contract in SDK `0.5.
|
|
21
|
+
for the installed-inventory-derived physical-runtime contract in SDK `0.5.12`.
|
|
22
22
|
|
|
23
23
|
| Specifier | Purpose |
|
|
24
24
|
| --- | --- |
|
|
@@ -748,7 +748,7 @@ deterministic map. The package root also contains the public
|
|
|
748
748
|
{
|
|
749
749
|
schemaVersion: 1,
|
|
750
750
|
kind: 'arcane-app-runtime-projection',
|
|
751
|
-
sdkVersion: '0.5.
|
|
751
|
+
sdkVersion: '0.5.12',
|
|
752
752
|
pathPrefix: 'arcane/',
|
|
753
753
|
files: [{path}]
|
|
754
754
|
}
|
|
@@ -2667,7 +2667,7 @@ The import-map operation also reports the stable operation-specific strings
|
|
|
2667
2667
|
`ARCANE_IMPORT_MAP_INVALID`, `ARCANE_IMPORT_MAP_UNRESOLVED`, and
|
|
2668
2668
|
`ARCANE_IMPORT_MAP_COLLISION`; package assembly can additionally report
|
|
2669
2669
|
`ARCANE_IMPORT_MAP_CLEANUP_FAILED`. They are normalized `ArcaneError.code`
|
|
2670
|
-
values, but are not properties added to this general registry in SDK `0.5.
|
|
2670
|
+
values, but are not properties added to this general registry in SDK `0.5.12`.
|
|
2671
2671
|
|
|
2672
2672
|
### Value and import
|
|
2673
2673
|
|
|
@@ -3437,7 +3437,7 @@ workspace it additionally returns the exact installed package authority:
|
|
|
3437
3437
|
packageSource,
|
|
3438
3438
|
canonicalPackageRoot,
|
|
3439
3439
|
packageName: 'arcane-os',
|
|
3440
|
-
packageVersion: '0.5.
|
|
3440
|
+
packageVersion: '0.5.12',
|
|
3441
3441
|
runtimeRoot,
|
|
3442
3442
|
browserRuntimeRoot
|
|
3443
3443
|
}
|
|
@@ -3445,9 +3445,9 @@ workspace it additionally returns the exact installed package authority:
|
|
|
3445
3445
|
```
|
|
3446
3446
|
|
|
3447
3447
|
The dependency can be named `arcane-os` or be one exact npm alias for
|
|
3448
|
-
`npm:arcane-os@0.5.
|
|
3448
|
+
`npm:arcane-os@0.5.12`. The selected installation must still be one direct,
|
|
3449
3449
|
physical, non-link package directory whose manifest identifies exactly as
|
|
3450
|
-
`arcane-os@0.5.
|
|
3450
|
+
`arcane-os@0.5.12`; duplicate canonical/alias declarations reject.
|
|
3451
3451
|
`allowMissingManagedImportMap` is an internal packaging/development seam. An
|
|
3452
3452
|
ordinary caller should leave it `false`.
|
|
3453
3453
|
|
package/package.json
CHANGED
|
@@ -5673,7 +5673,8 @@ class AI {
|
|
|
5673
5673
|
|
|
5674
5674
|
streamTTS(
|
|
5675
5675
|
text='',
|
|
5676
|
-
end=false
|
|
5676
|
+
end=false,
|
|
5677
|
+
options={}
|
|
5677
5678
|
){
|
|
5678
5679
|
if(this.muted){
|
|
5679
5680
|
if(end){
|
|
@@ -5682,6 +5683,12 @@ class AI {
|
|
|
5682
5683
|
return Promise.resolve(false);
|
|
5683
5684
|
}
|
|
5684
5685
|
|
|
5686
|
+
const {voice,speed,waitForPlayback=false}=options;
|
|
5687
|
+
const pauseAfterMs=Number(options.pauseAfterMs??0);
|
|
5688
|
+
if(!Number.isFinite(pauseAfterMs)||pauseAfterMs<0){
|
|
5689
|
+
throw new RangeError('Speech pauses must be a nonnegative number of milliseconds.');
|
|
5690
|
+
}
|
|
5691
|
+
|
|
5685
5692
|
this.audioMessageChunks+=String(text||'');
|
|
5686
5693
|
const outputs=this.#extractSpeechSegments(end);
|
|
5687
5694
|
|
|
@@ -5702,8 +5709,13 @@ class AI {
|
|
|
5702
5709
|
const generation=this.speechGeneration;
|
|
5703
5710
|
const jobs=[];
|
|
5704
5711
|
|
|
5705
|
-
for(const output of outputs){
|
|
5706
|
-
jobs.push(this.#queueSpeechJob(output,generation
|
|
5712
|
+
for(const [index,output] of outputs.entries()){
|
|
5713
|
+
jobs.push(this.#queueSpeechJob(output,generation,{
|
|
5714
|
+
voice,
|
|
5715
|
+
speed,
|
|
5716
|
+
waitForPlayback,
|
|
5717
|
+
pauseAfterMs:index===outputs.length-1?pauseAfterMs:0
|
|
5718
|
+
}));
|
|
5707
5719
|
}
|
|
5708
5720
|
|
|
5709
5721
|
return Promise.all(jobs).then(
|
|
@@ -5857,7 +5869,7 @@ class AI {
|
|
|
5857
5869
|
return this.#speechAbbreviations.has(token);
|
|
5858
5870
|
}
|
|
5859
5871
|
|
|
5860
|
-
#queueSpeechJob(text,generation){
|
|
5872
|
+
#queueSpeechJob(text,generation,options={}){
|
|
5861
5873
|
const job={
|
|
5862
5874
|
abortController:null,
|
|
5863
5875
|
audioBuffer:null,
|
|
@@ -5867,13 +5879,22 @@ class AI {
|
|
|
5867
5879
|
scheduledStart:null,
|
|
5868
5880
|
sourceNode:null,
|
|
5869
5881
|
state:'queued',
|
|
5870
|
-
text
|
|
5882
|
+
text,
|
|
5883
|
+
voice:options.voice,
|
|
5884
|
+
speed:options.speed,
|
|
5885
|
+
pauseAfterMs:options.pauseAfterMs??0,
|
|
5886
|
+
resolvePlayback:null
|
|
5871
5887
|
};
|
|
5872
5888
|
const runtime=this;
|
|
5889
|
+
const playback=options.waitForPlayback===true
|
|
5890
|
+
?new Promise(function captureSpeechPlaybackCompletion(resolve){
|
|
5891
|
+
job.resolvePlayback=resolve;
|
|
5892
|
+
})
|
|
5893
|
+
:null;
|
|
5873
5894
|
|
|
5874
5895
|
this.speechJobs.push(job);
|
|
5875
5896
|
|
|
5876
|
-
|
|
5897
|
+
const preparation=Promise.resolve().then(
|
|
5877
5898
|
function synthesizeAvailableSpeech(){
|
|
5878
5899
|
return runtime.#prepareSpeechJob(job);
|
|
5879
5900
|
}
|
|
@@ -5886,6 +5907,7 @@ class AI {
|
|
|
5886
5907
|
);
|
|
5887
5908
|
}
|
|
5888
5909
|
);
|
|
5910
|
+
return playback||preparation;
|
|
5889
5911
|
}
|
|
5890
5912
|
|
|
5891
5913
|
async #prepareSpeechJob(job){
|
|
@@ -5914,16 +5936,18 @@ class AI {
|
|
|
5914
5936
|
async #requestSpeechAudio(job){
|
|
5915
5937
|
job.abortController=new AbortController();
|
|
5916
5938
|
const selection=this.#providerRuntime.selection('tts');
|
|
5917
|
-
const voice=
|
|
5939
|
+
const voice=job.voice===undefined
|
|
5940
|
+
?(selection?this.#providerSpeechVoice():null)
|
|
5941
|
+
:job.voice;
|
|
5918
5942
|
const response=await this.fetchTTS(
|
|
5919
5943
|
{
|
|
5920
5944
|
model:selection?.modelId||this.modelTTS,
|
|
5921
5945
|
input:job.text,
|
|
5922
|
-
...(voice?{voice}:{}),
|
|
5946
|
+
...(job.voice!==undefined||voice?{voice}:{}),
|
|
5923
5947
|
responseFormat:selection
|
|
5924
5948
|
?this.#providerSpeechResponseFormat()
|
|
5925
5949
|
:this.audioFormat,
|
|
5926
|
-
speed:this.voiceSpeed
|
|
5950
|
+
speed:job.speed===undefined?this.voiceSpeed:job.speed
|
|
5927
5951
|
},
|
|
5928
5952
|
job.abortController.signal
|
|
5929
5953
|
);
|
|
@@ -6294,6 +6318,8 @@ class AI {
|
|
|
6294
6318
|
for(const job of this.speechJobs){
|
|
6295
6319
|
job.abortController?.abort();
|
|
6296
6320
|
job.state='cancelled';
|
|
6321
|
+
job.resolvePlayback?.(false);
|
|
6322
|
+
job.resolvePlayback=null;
|
|
6297
6323
|
|
|
6298
6324
|
if(job.sourceNode){
|
|
6299
6325
|
job.sourceNode.onended=null;
|
|
@@ -6370,6 +6396,22 @@ class AI {
|
|
|
6370
6396
|
if(attempt===this.speechResumeAttempt){
|
|
6371
6397
|
this.speechResumePending=false;
|
|
6372
6398
|
}
|
|
6399
|
+
if(context?.state==='closed'){
|
|
6400
|
+
this.#clearSpeechUnlock();
|
|
6401
|
+
const jobs=this.speechJobs.filter(function usesClosedSpeechContext(job){
|
|
6402
|
+
return job.audioContext===context;
|
|
6403
|
+
});
|
|
6404
|
+
if(!jobs.length){
|
|
6405
|
+
this.#publishTTSFailure(error,{
|
|
6406
|
+
boundary:'playback-resume',
|
|
6407
|
+
generation:this.speechGeneration
|
|
6408
|
+
});
|
|
6409
|
+
}
|
|
6410
|
+
for(const job of jobs){
|
|
6411
|
+
this.#failSpeechJob(job,error,'playback-resume');
|
|
6412
|
+
}
|
|
6413
|
+
return false;
|
|
6414
|
+
}
|
|
6373
6415
|
this.#waitForSpeechGesture(error,context);
|
|
6374
6416
|
if(error?.name!=='NotAllowedError'){
|
|
6375
6417
|
this.#publishTTSFailure(error,{
|
|
@@ -6543,7 +6585,7 @@ class AI {
|
|
|
6543
6585
|
job.state='scheduled';
|
|
6544
6586
|
job.scheduledStart=scheduledStart;
|
|
6545
6587
|
job.scheduledEnd=hasKnownDuration
|
|
6546
|
-
?scheduledStart+duration
|
|
6588
|
+
?scheduledStart+duration+(job.pauseAfterMs??0)/1000
|
|
6547
6589
|
:null;
|
|
6548
6590
|
job.sourceNode.__arcaneStarted=true;
|
|
6549
6591
|
if(!this.currentSpeechJob){
|
|
@@ -6606,6 +6648,11 @@ class AI {
|
|
|
6606
6648
|
job.sourceNode.onended=null;
|
|
6607
6649
|
}
|
|
6608
6650
|
|
|
6651
|
+
if(job.scheduledEnd===null&&job.pauseAfterMs>0){
|
|
6652
|
+
this.speechScheduleContext=job.audioContext;
|
|
6653
|
+
this.speechScheduleTime=
|
|
6654
|
+
(Number(job.audioContext?.currentTime)||0)+job.pauseAfterMs/1000;
|
|
6655
|
+
}
|
|
6609
6656
|
job.state='complete';
|
|
6610
6657
|
this.#removeSpeechJob(job);
|
|
6611
6658
|
|
|
@@ -6727,6 +6774,8 @@ class AI {
|
|
|
6727
6774
|
}
|
|
6728
6775
|
|
|
6729
6776
|
#removeSpeechJob(job){
|
|
6777
|
+
job.resolvePlayback?.(job.state==='complete');
|
|
6778
|
+
job.resolvePlayback=null;
|
|
6730
6779
|
const jobIndex=this.speechJobs.indexOf(job);
|
|
6731
6780
|
|
|
6732
6781
|
if(jobIndex>=0){
|