arcane-os 0.59.0 → 0.59.1

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.59.1
4
+
5
+ - Forward the existing AI synthesis signal into native Core synthesis and
6
+ preserve the established AI cancellation error contract.
7
+ - Carry `AI.fetchSTT(audio, signal)` cancellation through
8
+ `Arcane.speech.transcribe(request, {signal})` into the existing Core request
9
+ lifetime. Preserve complete requests and results, one-argument facade calls,
10
+ unrelated errors and the 180-second timeout. Actual inference interruption
11
+ and resource release remain with the selected speech service.
12
+ - No speech engine, model, runtime dependency, default-provider switch or data
13
+ migration is introduced.
14
+
3
15
  ## 0.59.0
4
16
 
5
17
  - Reconcile marked generated PWA references when a root application's PWA is
package/README.md CHANGED
@@ -20,7 +20,7 @@ selected SDK projection or an explicit live SDK source mount. Both profiles
20
20
  share the theme, packaging, event, cancellation,
21
21
  and browser run contracts while retaining their selected application layout.
22
22
 
23
- This checkout defines the `0.59.0` SDK contract. Development applications declare
23
+ This checkout defines the `0.59.1` SDK contract. Development applications declare
24
24
  `arcane-os` as `latest` and retain their lockfile. Exact SDK pins begin when Roshi
25
25
  designates a production build. Follow [Consumer updates](docs/consumer-updates.md)
26
26
  to refresh and compare the installed SDK and lockfile with the published channel;
@@ -569,7 +569,7 @@ export function createCoreFacade(client){
569
569
  mail:{send:request=>invoke('mail.send',request??{},{timeoutMs:450000})},
570
570
  speech:{status:()=>invoke('speech.status',{},{timeoutMs:10000}),
571
571
  synthesize:(request,options)=>invoke('speech.synthesize',request??{},{timeoutMs:180000,signal:options?.signal}),
572
- transcribe:request=>invoke('speech.transcribe',request??{},{timeoutMs:180000})},
572
+ transcribe:(request,options)=>invoke('speech.transcribe',request??{},{timeoutMs:180000,signal:options?.signal})},
573
573
  localAI:{status:()=>invoke('localai.status',{},{timeoutMs:15000}),
574
574
  ensurePlatform:()=>invoke('localai.platform.ensure',{},long),recover:request=>invoke('localai.services.recover',request??{},long),
575
575
  setParallelRequests:request=>invoke('localai.parallel.requests.set',request??{},long),
@@ -42,6 +42,7 @@ alone does not make bare module names resolve in a browser.
42
42
  | Inspect complete AI and speech calls using the shared developer-mode preference | [Shared logger](sdk-api.md#arcanelogging) and [speech developer diagnostics](ai/browser-speech.md#developer-diagnostics) |
43
43
  | Use the `arcane` command | [CLI reference](cli.md) |
44
44
  | Install an app and cache selected resources offline | [Progressive web applications](pwa.md) |
45
+ | Disable source PWA generation or explicitly retire confirmed generated output | [Source PWA retirement](pwa.md#disable-source-pwa-generation-and-retire-generated-output) |
45
46
  | Generate named browser imports or inspect the selected physical runtime | [`arcane import-map`](cli.md#arcane-import-map) and [browser runtime delivery](protocols.md#browser-runtime-delivery) |
46
47
  | Connect an application through the shared WebSocket transport | [Shared WebSocket clients](websocket-client.md) |
47
48
  | Choose browser, native, cloud, or cross-host behavior | [Availability and normalization](availability-and-normalization.md) |
@@ -51,12 +52,14 @@ alone does not make bare module names resolve in a browser.
51
52
  | Submit complete speech parts immediately and play them in order | [`SpeechPlayback`](runtime-modules.md#speechplaybackjs) and the [basic browser example](ai/browser-speech.md#play-a-complete-array-with-speechplayback) |
52
53
  | Call `globalThis.Arcane` | [Arcane Core API](core/arcane-api.md) |
53
54
  | Connect a browser to one Core transport | [Core browser client](core-client.md) |
55
+ | Cancel one Core speech synthesis request without changing its payload | [Speech request lifetime](core-client.md#events-and-request-lifetime) and [Core facade](sdk-api.md#createcorefacade) |
54
56
  | Compose native Core dispatch, service lifecycle, and stdio hosting | [Native Core runtime](core-runtime.md) |
55
57
  | Run application-selected llama.cpp, Ollama or ONNX through Core | [Local AI through Core](local-ai.md) |
56
58
  | Retain a Nemotron model and diarize caller-fed audio streams | [Native speaker diarization](diarization.md) |
57
59
  | Persist application-selected preferences through Core | [Core preferences service](core-preferences.md) |
58
60
  | Read complete selected Git text without changing a checkout | [Git text snapshots](git-text-snapshot.md) |
59
61
  | Build an installed-SDK portable Core payload | [Portable Core packaging](core-native-packaging.md) |
62
+ | Pass host-selected state defaults and unchanged explicit launch values to services | [Launch-time locations](core-native-packaging.md#launch-time-locations) |
60
63
  | Build a Windows executable without an OS checkout | [Windows executable packaging](core-native-packaging.md#windows-executable) |
61
64
  | Compose a Mac application with an architecture-matched host | [macOS application composition](core-native-packaging.md#macos-application-composition) |
62
65
  | Subscribe to native events | [Arcane event reference](core/arcane-events.md) |
@@ -564,7 +564,7 @@ defaulting.
564
564
 
565
565
  ### Speech transcription request
566
566
 
567
- `Arcane.speech.transcribe(request)` accepts an exact
567
+ `Arcane.speech.transcribe(request, options?)` accepts an exact
568
568
  `SpeechTranscriptionRequest`.
569
569
 
570
570
  | Field | Type | Required | Constraints / default | Description |
@@ -573,6 +573,19 @@ defaulting.
573
573
  | `mimeType` | `string` | No | Default `"audio/webm"`; base type must be `audio/webm` | Media type; codec parameters may follow. |
574
574
  | `model` | `string` | No | Default `"whisper-small"`; `whisper(?:[._-][a-z0-9]+)*` | Whisper identifier. The fixed service rejects unsupported variants. |
575
575
 
576
+ ### Speech transcription controls
577
+
578
+ The optional second argument is `SpeechTranscriptionControls`:
579
+
580
+ | Field | Type | Required | Default | Description |
581
+ |---|---|---:|---|---|
582
+ | `signal` | `AbortSignal` | No | No caller signal | Cancels this request through Core. The facade forwards it separately from the complete audio request; the registered service owns actual engine interruption. |
583
+
584
+ Existing one-argument calls retain their behavior. The facade's request timeout
585
+ remains 180 seconds. A pre-aborted signal dispatches no request, and an
586
+ in-flight abort cancels the request and suppresses late responses. Other
587
+ properties of this controls record are unused; they do not enter the payload.
588
+
576
589
  ### Speech transcription result
577
590
 
578
591
  | Field | Type | Required | Constraints / default | Description |
@@ -105,7 +105,7 @@ directly.
105
105
  | `Arcane.localAI.setParallelRequests(request)` | `request`: [`LocalAIParallelRequestsRequest`](arcane-ai-contracts.md#local-ai-parallel-request-configuration) | [`Promise<LocalAIParallelRequestsResult>`](arcane-ai-contracts.md#local-ai-parallel-request-configuration) | Solves one app-owned verified model/context's maximum directly from native model and memory/resource evidence without a product ceiling, clamps a positive request to that result (`0` requests the maximum), and changes the machine-wide managed Ollama setting only when needed. A tentative change uses one fresh stopped-service snapshot before the final value is written, then Core ensures, loads, and confirms the exact model. A restart unloads resident models. Automatic mutation currently requires the dedicated `ai.runtime.manage` capability on Microsoft NT desktop Core and operating-system authorization; Linux returns administrator-managed systemd guidance, and Android user-managed loopback sessions do not invoke it. |
106
106
  | `Arcane.speech.status()` | None | [`Promise<SpeechStatus>`](arcane-ai-contracts.md#speech-status) | Reads bounded, independent Kokoro and Whisper readiness through Core or an admitted Android native host. Requires `ai.inference`. |
107
107
  | `Arcane.speech.synthesize(request)` | `request`: [`SpeechSynthesisRequest`](arcane-ai-contracts.md#speech-synthesis-request) | [`Promise<SpeechSynthesisResult>`](arcane-ai-contracts.md#speech-synthesis-result) | Synthesizes bounded local speech through the native host and fixed loopback runtime. Requires `ai.inference`. |
108
- | `Arcane.speech.transcribe(request)` | `request`: [`SpeechTranscriptionRequest`](arcane-ai-contracts.md#speech-transcription-request) | [`Promise<SpeechTranscriptionResult>`](arcane-ai-contracts.md#speech-transcription-result) | Sends bounded canonical base64 bytes labeled `audio/webm` to local Whisper through the native host. The bridge validates encoding, label, and bounds; the fixed service parses the media container. Requires `ai.inference`. |
108
+ | `Arcane.speech.transcribe(request, options?)` | `request`: [`SpeechTranscriptionRequest`](arcane-ai-contracts.md#speech-transcription-request); `options?`: [`SpeechTranscriptionControls`](arcane-ai-contracts.md#speech-transcription-controls) | [`Promise<SpeechTranscriptionResult>`](arcane-ai-contracts.md#speech-transcription-result) | Sends the complete request to the selected native transcription service; optional cancellation reaches Core's request lifetime. The registered host service owns media decoding and actual engine interruption. |
109
109
  | `Arcane.ollama.version()` | None | [`Promise<OllamaVersionResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Gets the managed Ollama version for Settings, Terminal, and Shell diagnostics. |
110
110
  | `Arcane.ollama.models()` | None | [`Promise<OllamaModelsResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Lists the raw provider inventory envelope; it is not the application admission catalog. |
111
111
  | `Arcane.ollama.list()` | None | [`Promise<OllamaModelsResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Alias of the raw `models()` inventory. |
@@ -703,7 +703,7 @@ console.info(result.contentType, result.audioBase64.length);
703
703
 
704
704
  ### Overview
705
705
 
706
- `Arcane.speech.transcribe(request)` sends bounded caller-supplied audio bytes,
706
+ `Arcane.speech.transcribe(request, options?)` sends bounded caller-supplied audio bytes,
707
707
  labeled as WebM, to the fixed local transcription service. Use it after local
708
708
  capture permission and recording have succeeded; the method itself does not
709
709
  capture audio or grant microphone permission.
@@ -739,18 +739,21 @@ work after `ANDROID_SPEECH_QUEUE_FULL`.
739
739
  ### Streaming, cancellation, and events
740
740
 
741
741
  Transcription resolves one complete text result and emits no method event. The
742
- wrapper timeout is 180 seconds and no signal is exposed. Core and Android do
743
- not promise cancellation when the renderer stops waiting.
742
+ wrapper timeout remains 180 seconds. Optional `{signal}` controls the Core
743
+ request lifetime separately from the complete audio payload. Pre-abort sends
744
+ no request; in-flight abort cancels that request and suppresses late responses.
745
+ The registered native service owns actual inference interruption and resource
746
+ release. `AI.fetchSTT(audio, signal)` forwards its signal through this call.
744
747
 
745
748
  ### Example
746
749
 
747
750
  ```javascript
748
- async function transcribeRecordedWebM(audioBase64) {
751
+ async function transcribeRecordedWebM(audioBase64, signal) {
749
752
  const result = await globalThis.Arcane.speech.transcribe({
750
753
  audioBase64: audioBase64,
751
754
  mimeType: 'audio/webm',
752
755
  model: 'whisper-small'
753
- });
756
+ }, {signal});
754
757
  return result.text;
755
758
  }
756
759
  ```
@@ -84,6 +84,13 @@ signal sends no synthesis request; an in-flight abort sends `request.cancel`
84
84
  and suppresses late responses. Actual synthesis interruption depends on the
85
85
  registered speech service and its engine; the facade supplies no speech engine.
86
86
 
87
+ `Arcane.speech.transcribe(request, {signal})` forwards cancellation through the
88
+ same request lifetime and retains its 180,000 ms timeout and complete request.
89
+ `AI.fetchSTT(audio, signal)` carries that signal into the native call. A
90
+ pre-aborted signal sends no transcription request; an in-flight abort sends
91
+ `request.cancel` and suppresses late responses. The registered transcription
92
+ service owns interruption and release of its actual engine operation.
93
+
87
94
  ## Events and request lifetime
88
95
 
89
96
  `events.on(name, listener)`, `once(name, listener)` and
@@ -4563,6 +4563,12 @@ The object includes `importMap(options)`, which merges defaults with explicit
4563
4563
  call options and refreshes every directly navigable descriptor-selected browser
4564
4564
  document for one selected app. The equivalent generic route is
4565
4565
  `execute('import-map', options)`.
4566
+ For a standalone root app with `pwa.enabled:false`, ordinary refresh removes
4567
+ marked SDK-generated PWA references from selected documents. An explicit
4568
+ `importMap({retireGeneratedPwa:true})` also retires the four standard root PWA
4569
+ outputs and matching older manifest references after the application owner
4570
+ confirms they are generated. See [disabled-PWA retirement](pwa.md#disable-source-pwa-generation-and-retire-generated-output)
4571
+ for the required source-selection adjustment and preserved content.
4566
4572
  It also includes `upgrade(options)`, which performs the explicit installed-SDK
4567
4573
  consumer upgrade described by `upgradeApplication()`, and
4568
4574
  `updateCheck(options)`, which invokes `checkSdkUpdate()` once. Constructing the
@@ -4685,6 +4691,25 @@ documents through sequential writes and has no supported dry-run or
4685
4691
  all-file transaction. An error or cancellation can leave completed writes in
4686
4692
  place; rerun the operation after resolving the cause.
4687
4693
 
4694
+ For a standalone `appsRoot:'.'` app with `pwa.enabled:false`, ordinary refresh
4695
+ removes active generated registration scripts and matching manifest relationships
4696
+ marked `data-arcane-manifest`. Unmarked references and existing PWA files remain.
4697
+ Set `retireGeneratedPwa:true` only after confirming generated ownership of the
4698
+ matching root manifest references and all four standard outputs:
4699
+ `arcane.webmanifest`, `arcane-offline.json`, `arcane-sw.js` and `arcane-pwa.mjs`.
4700
+ Remove those generated outputs from required `package.include` entries first,
4701
+ and confirm that unselected documents no longer need them. The operation writes
4702
+ selected reference changes before deleting these files; its
4703
+ `import-map.root-files.completed` event reports actual removed paths in
4704
+ `retiredPwa`. Repeated retirement accepts already-absent output.
4705
+
4706
+ An omitted PWA record selects no retirement; an enabled record keeps normal
4707
+ generation. The option belongs only to this explicit import-map API route.
4708
+ Ordinary development refresh does not forward file-retirement authority, and
4709
+ there is no new CLI flag. Other files, unselected/inactive HTML, authored content
4710
+ and browser registrations, caches and saved data keep their existing ownership.
4711
+ See the complete [source PWA contract](pwa.md#disable-source-pwa-generation-and-retire-generated-output).
4712
+
4688
4713
  The exact command `'upgrade'` dispatches `upgradeApplication(options)`. It is
4689
4714
  external-workspace-only and runs that application's ordinary `npm upgrade`
4690
4715
  command. It does not independently reconcile the installed SDK projection,
@@ -6899,6 +6924,14 @@ Import it from `arcane-os/core/client`. The result includes `runtime`, `events`,
6899
6924
  `Error` and the existing `ai`, `environment`, `mail`, `speech`, `localAI`,
6900
6925
  `ollama`, application, platform, storage and other host namespaces.
6901
6926
 
6927
+ `facade.speech.synthesize(request, {signal})` accepts an optional `AbortSignal`
6928
+ through the same correlated request lifetime. The complete request and existing
6929
+ 180,000 ms timeout remain unchanged. A pre-aborted signal sends no synthesis
6930
+ request; an in-flight abort emits that request's `request.cancel`, rejects with
6931
+ `ARCANE_REQUEST_ABORTED` and leaves unrelated requests active. Late responses
6932
+ cannot settle the cancelled request. Actual native synthesis interruption belongs
6933
+ to the registered service and engine; this facade supplies no engine.
6934
+
6902
6935
  ### Availability and normalization
6903
6936
 
6904
6937
  **Browser and native WebView JavaScript hosts with a Core client.** Creating the
@@ -7560,8 +7593,9 @@ import createDiarizationService from 'arcane-os/core/diarization';
7560
7593
 
7561
7594
  ### Overview
7562
7595
 
7563
- Reads only the complete JSON object explicitly selected by
7564
- `--arcane-launch-config <path>`; it does not search for application configuration.
7596
+ Reads the complete JSON object explicitly selected by
7597
+ `--arcane-launch-config <path>`, with an optional separately supplied native host
7598
+ state-directory default. It does not search for application configuration.
7565
7599
 
7566
7600
  ### Signature and result
7567
7601
 
@@ -7569,11 +7603,15 @@ Reads only the complete JSON object explicitly selected by
7569
7603
  async readCoreLaunchContext({argv=process.argv.slice(2)}={})
7570
7604
  ```
7571
7605
 
7572
- Import it from `arcane-os/core/host`. The promise resolves to `{}` when the flag
7573
- is absent, or the complete parsed object when present. A missing flag value,
7574
- unreadable file, malformed JSON or non-object value rejects. Relative paths use
7575
- the process working directory. The reader does not rewrite content or mutate
7576
- the environment.
7606
+ Import it from `arcane-os/core/host`. `--arcane-host-state-root <directory>`
7607
+ supplies a `stateRoot` default; every field from the explicit launch JSON object
7608
+ then takes precedence unchanged, including a relative, null or other explicitly
7609
+ present `stateRoot`. With neither argument, the promise resolves to `{}`.
7610
+ A missing argument value, unreadable launch file, malformed JSON or non-object
7611
+ value rejects. Relative launch-file paths use the process working directory.
7612
+ The reader does not choose, resolve or validate the state directory, rewrite
7613
+ content, discover or migrate stored data, or mutate the environment. An
7614
+ application-selected `preferencesFile` remains a separate unchanged field.
7577
7615
 
7578
7616
  ```javascript
7579
7617
  import {readCoreLaunchContext} from 'arcane-os/core/host';
@@ -7584,7 +7622,10 @@ const launchContext = await readCoreLaunchContext();
7584
7622
  The generated entry supplies artifact-derived `appRoot`, then applies the whole
7585
7623
  explicit context and passes the same object as every service factory's second
7586
7624
  argument. Authored service options remain the first argument. Workspace/state
7587
- locations and additional fields belong to the launcher/application. See
7625
+ locations and additional fields belong to the launcher/application. Windows and
7626
+ Mac launchers forward their actual host-selected state directory through the
7627
+ separate argument; other composing hosts may use the same seam. This JavaScript
7628
+ contract does not establish a compiled host or matching release archive. See
7588
7629
  [launch-time locations](core-native-packaging.md#launch-time-locations).
7589
7630
 
7590
7631
  ## createCoreLocalAIProvider()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-os",
3
- "version": "0.59.0",
3
+ "version": "0.59.1",
4
4
  "description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",
@@ -4084,11 +4084,19 @@ class AI {
4084
4084
  if(signal?.aborted){
4085
4085
  throw normalizeAIRequestAbort(signal.reason);
4086
4086
  }
4087
- const response=await nativeSpeech.transcribe({
4088
- audioBase64:this.#arrayBufferToBase64(audioBytes),
4089
- mimeType,
4090
- model
4091
- });
4087
+ let response;
4088
+ try{
4089
+ response=await nativeSpeech.transcribe({
4090
+ audioBase64:this.#arrayBufferToBase64(audioBytes),
4091
+ mimeType,
4092
+ model
4093
+ },{signal});
4094
+ }catch(error){
4095
+ if(isAIRequestAbort(error,signal)){
4096
+ throw normalizeAIRequestAbort(error);
4097
+ }
4098
+ throw error;
4099
+ }
4092
4100
  if(signal?.aborted){
4093
4101
  throw normalizeAIRequestAbort(signal.reason);
4094
4102
  }
@@ -4138,13 +4146,21 @@ class AI {
4138
4146
  const speed=is.finite(payload.speed)?payload.speed:this.voiceSpeed;
4139
4147
  const nativeSpeech=this.#nativeSpeech(this.ttsService,'tts');
4140
4148
  if(nativeSpeech){
4141
- const response=await nativeSpeech.synthesize({
4142
- model,
4143
- voice,
4144
- input,
4145
- responseFormat,
4146
- speed
4147
- });
4149
+ let response;
4150
+ try{
4151
+ response=await nativeSpeech.synthesize({
4152
+ model,
4153
+ voice,
4154
+ input,
4155
+ responseFormat,
4156
+ speed
4157
+ },{signal});
4158
+ }catch(error){
4159
+ if(isAIRequestAbort(error,signal)){
4160
+ throw normalizeAIRequestAbort(error);
4161
+ }
4162
+ throw error;
4163
+ }
4148
4164
  if(signal?.aborted){
4149
4165
  throw normalizeAIRequestAbort(signal.reason);
4150
4166
  }