signalk-whisper 0.0.1 → 0.2.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/README.md +153 -9
- package/dist/config.d.ts +140 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +255 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/dist/service.d.ts +187 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +548 -0
- package/dist/service.js.map +1 -0
- package/dist/wyoming.d.ts +33 -0
- package/dist/wyoming.d.ts.map +1 -0
- package/dist/wyoming.js +115 -0
- package/dist/wyoming.js.map +1 -0
- package/package.json +64 -5
- package/public/172.mjs +1 -0
- package/public/540.mjs +2 -0
- package/public/540.mjs.LICENSE.txt +9 -0
- package/public/main.mjs +1 -0
- package/public/remoteEntry.js +1 -0
- package/index.js +0 -23
package/README.md
CHANGED
|
@@ -1,16 +1,160 @@
|
|
|
1
1
|
# signalk-whisper
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: ALPHA.** This SignalK Wyoming system is 100% vibecoded slop. I
|
|
4
|
+
> don't have the right hardware yet to test it, so I'm putting it out there
|
|
5
|
+
> for people to test in the meantime. It _should_ work. File issues for
|
|
6
|
+
> anything that doesn't.
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
## What is this?
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
Whisper speech-to-text for [Signal K](https://signalk.org) — it gives your
|
|
11
|
+
boat server "ears". The plugin runs the
|
|
12
|
+
[Whisper](https://github.com/rhasspy/wyoming-faster-whisper) speech
|
|
13
|
+
recognizer as a background service and takes care of everything around it:
|
|
14
|
+
starting it in a container (via the
|
|
15
|
+
[signalk-container](https://www.npmjs.com/package/signalk-container)
|
|
16
|
+
plugin), downloading the speech model, checking that it stays healthy, and
|
|
17
|
+
telling the rest of the voice stack where to find it. You never have to
|
|
18
|
+
touch docker or podman yourself.
|
|
19
|
+
|
|
20
|
+
It is the speech-to-text (STT) building block of the
|
|
21
|
+
[signalk-wyoming voice-assistant family](https://github.com/hoeken/signalk-wyoming)
|
|
22
|
+
— install it together with the `signalk-wyoming` orchestrator to get voice
|
|
23
|
+
commands on your boat. Because it speaks the standard
|
|
24
|
+
[Wyoming protocol](https://github.com/rhasspy/wyoming), it also works as a
|
|
25
|
+
standalone speech-to-text server for other software such as Home Assistant.
|
|
26
|
+
|
|
27
|
+
## Requirements
|
|
28
|
+
|
|
29
|
+
- Signal K server ≥ 2.x on **Node 24+**
|
|
30
|
+
- The **signalk-container** plugin with a working podman or docker runtime
|
|
31
|
+
- RAM for the model: the default `tiny-int8` uses roughly **400–500 MB
|
|
32
|
+
resident** (`base-int8` ≈ 700 MB). The container is capped at 1 GB by
|
|
33
|
+
default so a misbehaving model cannot starve the boat server. The full
|
|
34
|
+
voice stack with whisper is comfortable on a Pi 4/5 with 4 GB. (A
|
|
35
|
+
TTS-only voice install does not need this plugin at all.)
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
Install **signalk-whisper** from the Signal K App Store (or `npm install
|
|
40
|
+
signalk-whisper` in your server directory), enable it in Plugin Config, and
|
|
41
|
+
enable the signalk-container plugin if you have not already.
|
|
42
|
+
|
|
43
|
+
## Configuration
|
|
44
|
+
|
|
45
|
+
The plugin ships a graphical configuration panel (Server → Plugin Config →
|
|
46
|
+
Whisper STT) with a live container status card, a one-click image update
|
|
47
|
+
check/apply, a version dropdown fed by Docker Hub, and all the settings
|
|
48
|
+
below — with inline warnings if you pick a heavyweight model or open the
|
|
49
|
+
service to the network. On servers without custom-panel support you get a
|
|
50
|
+
plain settings form with the same options.
|
|
51
|
+
|
|
52
|
+
| Setting | Default | Notes |
|
|
53
|
+
| ------------------------ | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
54
|
+
| `model` | `tiny-int8` | One of `tiny-int8`, `base-int8`, `small-int8`, `medium-int8`, `tiny`, `tiny.en`, `base`, `base.en`, `small`, `small.en`, `medium.en`, `turbo`. int8 models are recommended (smaller + faster on CPU). See "Choosing a model". |
|
|
55
|
+
| `language` | `en` | Explicit language code. `auto` enables per-utterance detection but costs speed **and** accuracy on the small models — set it explicitly if you can. |
|
|
56
|
+
| `initialPrompt` | nautical word list | A list of words that biases recognition toward your vocabulary — the cheapest accuracy win available. See "The initial prompt". Empty disables it. |
|
|
57
|
+
| `imageTag` | `auto` | `auto` runs the pinned, tested upstream release (**3.5.0**) and follows plugin updates. Set an explicit tag to pin something else. |
|
|
58
|
+
| `port` | `10300` | Host TCP port — only used with `bind: 0.0.0.0`, where the service is published on exactly this port. With the default loopback networking the setting is ignored and a host port is assigned automatically. |
|
|
59
|
+
| `advanced.bind` | `127.0.0.1` | `127.0.0.1` keeps whisper local to the boat server (recommended — the orchestrator is its only intended consumer). `0.0.0.0` publishes it on all interfaces, e.g. to share it with Home Assistant. See Security. |
|
|
60
|
+
| `advanced.memoryLimit` | `1g` | Hard container memory cap (swap capped to the same value). |
|
|
61
|
+
| `advanced.restartPolicy` | `unless-stopped` | Container runtime restart policy. |
|
|
62
|
+
|
|
63
|
+
### Choosing a model
|
|
64
|
+
|
|
65
|
+
Bigger models transcribe more accurately but need more RAM and take longer
|
|
66
|
+
per utterance.
|
|
67
|
+
|
|
68
|
+
| Model | Download | Resident RAM | When |
|
|
69
|
+
| --------------------------------------- | -------------- | ------------ | ---------------------------------------------------------------------------- |
|
|
70
|
+
| `tiny-int8` | ≈ 43 MB | ≈ 400–500 MB | Default. Fine for short commands on a Pi 4. |
|
|
71
|
+
| `base-int8` | ≈ 80 MB | ≈ 700 MB | Recommended on a Pi 5 / x86 box — noticeably better accuracy. |
|
|
72
|
+
| `small-int8` / `medium-int8` | hundreds of MB | > 1 GB | Only with plenty of RAM/CPU; raise `memoryLimit`. |
|
|
73
|
+
| `tiny`–`small.en`, `medium.en`, `turbo` | larger (float) | more | The `.en` variants are English-only and slightly more accurate at each size. |
|
|
74
|
+
|
|
75
|
+
Transcription latency is the practical constraint: the signalk-wyoming
|
|
76
|
+
webapp's **Test screen** shows a per-transcription latency figure — use it
|
|
77
|
+
to decide whether your hardware can afford a bigger model.
|
|
78
|
+
|
|
79
|
+
(A model setting of `auto` is deliberately **not** offered: with this
|
|
80
|
+
service it can silently switch to a much larger non-Whisper backend and
|
|
81
|
+
download hundreds of MB.)
|
|
82
|
+
|
|
83
|
+
### The initial prompt
|
|
84
|
+
|
|
85
|
+
The shipped default biases Whisper toward sailing vocabulary:
|
|
86
|
+
|
|
87
|
+
> Genoa, jib, mainsail, spinnaker, windlass, gybe, tack, halyard, winch,
|
|
88
|
+
> anchor chain, rode, bilge, galley, helm, autopilot, waypoint, knots, port,
|
|
89
|
+
> starboard, bow, stern, leeward, windward, reef, furl, log position, anchor
|
|
90
|
+
> alarm, engine, throttle.
|
|
91
|
+
|
|
92
|
+
Customize it with words Whisper would otherwise mis-hear, for example:
|
|
93
|
+
|
|
94
|
+
- your **vessel name** ("Wildeling"),
|
|
95
|
+
- **local place and port names** ("Port Townsend, Deception Pass, Anacortes"),
|
|
96
|
+
- **boat-specific gear** ("watermaker, Hydrovane, staysail, preventer").
|
|
97
|
+
|
|
98
|
+
## First start & offline use
|
|
99
|
+
|
|
100
|
+
On first start (and after a model change) the container downloads the model
|
|
101
|
+
into this plugin's Signal K data directory — the download survives
|
|
102
|
+
container recreation and image updates, so it only happens once per model.
|
|
103
|
+
The plugin status shows _"starting — first start downloads the model
|
|
104
|
+
(tiny-int8 ≈ 43 MB, base-int8 ≈ 80 MB)"_ until the service answers; up to
|
|
105
|
+
10 minutes are allowed for slow connections.
|
|
106
|
+
|
|
107
|
+
**Do the first start (and any model change) while you have internet** — at
|
|
108
|
+
sea with no connectivity a never-downloaded model cannot load, and the
|
|
109
|
+
plugin will report the failure rather than sit silent.
|
|
110
|
+
|
|
111
|
+
## Using it from other software
|
|
112
|
+
|
|
113
|
+
Once ready, the service is a plain Wyoming STT server at
|
|
114
|
+
`tcp://<host>:<port>` (normally `tcp://127.0.0.1:10300`):
|
|
115
|
+
|
|
116
|
+
- **signalk-wyoming** discovers it automatically — nothing to configure.
|
|
117
|
+
- **Home Assistant** (or any other Wyoming client) can use it as an STT
|
|
118
|
+
provider: set `advanced.bind` to `0.0.0.0` and point HA's Wyoming
|
|
119
|
+
integration at `tcp://<boat-ip>:10300`.
|
|
120
|
+
|
|
121
|
+
## HTTP API
|
|
122
|
+
|
|
123
|
+
| Endpoint | Access | Purpose |
|
|
124
|
+
| ------------------------------------------------ | ---------------------- | ---------------------------------------------------------------------------------------------- |
|
|
125
|
+
| `GET /plugins/signalk-whisper/api/status` | any authenticated user | Current state: `{ status, uri, tag, containerState, lastHealth, info }` |
|
|
126
|
+
| `GET /plugins/signalk-whisper/api/versions` | any authenticated user | Available image versions from Docker Hub (feeds the config panel; works while plugin disabled) |
|
|
127
|
+
| `GET /plugins/signalk-whisper/api/update/check` | admin | Check whether a newer image is available |
|
|
128
|
+
| `POST /plugins/signalk-whisper/api/update/apply` | admin | Pull and switch to the newer image |
|
|
129
|
+
|
|
130
|
+
## Health & notifications
|
|
131
|
+
|
|
132
|
+
The plugin checks the service every 30 seconds. If it stops answering,
|
|
133
|
+
after three consecutive failures (about 90 seconds) it raises the Signal K
|
|
134
|
+
notification **`notifications.voice.whisper`** with `state: "alarm"` and
|
|
135
|
+
shows an error in Plugin Config. When the service answers again everything
|
|
136
|
+
clears back to normal automatically — no action needed.
|
|
137
|
+
|
|
138
|
+
The alarm is visual-only by design: plugins that read notifications aloud
|
|
139
|
+
won't try to _speak_ the voice stack's own failure.
|
|
140
|
+
|
|
141
|
+
## Security
|
|
142
|
+
|
|
143
|
+
Wyoming has **no authentication**. Anyone who can reach the port can feed
|
|
144
|
+
audio to (and read transcripts from) the service. The default
|
|
145
|
+
`bind: 127.0.0.1` keeps it unreachable from the network — only the Signal K
|
|
146
|
+
host (and its containers) can use it. Only switch to `0.0.0.0` on a trusted
|
|
147
|
+
network, and prefer a firewall rule or VLAN that restricts the port to the
|
|
148
|
+
machines that need it (see the signalk-wyoming documentation for a
|
|
149
|
+
marina-wifi hardening recipe).
|
|
150
|
+
|
|
151
|
+
## Development
|
|
152
|
+
|
|
153
|
+
See [DEVELOPERS.md](DEVELOPERS.md) for the code layout, build/test
|
|
154
|
+
commands, architecture notes, and the service-discovery contract.
|
|
13
155
|
|
|
14
156
|
## License
|
|
15
157
|
|
|
16
|
-
Apache-2.0
|
|
158
|
+
Apache-2.0 © hoeken. The upstream Whisper service is
|
|
159
|
+
[rhasspy/wyoming-faster-whisper](https://github.com/rhasspy/wyoming-faster-whisper)
|
|
160
|
+
(MIT).
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* signalk-whisper configuration: JSON schema, defaults, and the pure
|
|
3
|
+
* settings → ContainerConfig mapping consumed by signalk-container-helper.
|
|
4
|
+
*/
|
|
5
|
+
import type { ContainerConfig } from "signalk-container-helper";
|
|
6
|
+
export declare const PLUGIN_ID = "signalk-whisper";
|
|
7
|
+
export declare const PLUGIN_NAME = "Whisper STT (Wyoming)";
|
|
8
|
+
export declare const SERVICE_TYPE = "asr";
|
|
9
|
+
/** Unprefixed container name; runs as `sk-whisper` on the host runtime. */
|
|
10
|
+
export declare const CONTAINER_NAME = "whisper";
|
|
11
|
+
export declare const IMAGE = "rhasspy/wyoming-whisper";
|
|
12
|
+
/** Pinned, tested upstream release; `imageTag: "auto"` resolves to this. */
|
|
13
|
+
export declare const PINNED_TAG = "3.5.0";
|
|
14
|
+
/**
|
|
15
|
+
* Container-side Wyoming port. The image bakes `--uri tcp://0.0.0.0:10300`
|
|
16
|
+
* into its entrypoint, so the container ALWAYS listens on 10300 internally.
|
|
17
|
+
*/
|
|
18
|
+
export declare const WYOMING_PORT = 10300;
|
|
19
|
+
export declare const NOTIFICATION_PATH = "notifications.voice.whisper";
|
|
20
|
+
/** First-start model download sizes surfaced in plugin status / README. */
|
|
21
|
+
export declare const DOWNLOAD_HINT = "tiny-int8 \u2248 43 MB, base-int8 \u2248 80 MB";
|
|
22
|
+
/**
|
|
23
|
+
* Models accepted by the `--model` flag. NEVER "auto": with the 3.5.0 image
|
|
24
|
+
* `--model auto --language en` silently switches to a ~0.6B-parameter
|
|
25
|
+
* sherpa/Parakeet backend and downloads hundreds of MB — a disaster on a
|
|
26
|
+
* boat server. int8 models are the recommended choice.
|
|
27
|
+
*/
|
|
28
|
+
export declare const WHISPER_MODELS: readonly ["tiny-int8", "base-int8", "small-int8", "medium-int8", "tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium.en", "turbo"];
|
|
29
|
+
export type WhisperModel = (typeof WHISPER_MODELS)[number];
|
|
30
|
+
/**
|
|
31
|
+
* Default `--initial-prompt`: nautical vocabulary that biases Whisper toward
|
|
32
|
+
* sailing terms. The cheapest accuracy win available — user-editable.
|
|
33
|
+
*/
|
|
34
|
+
export declare const NAUTICAL_PROMPT: string;
|
|
35
|
+
export interface AdvancedSettings {
|
|
36
|
+
bind: "127.0.0.1" | "0.0.0.0";
|
|
37
|
+
memoryLimit: string;
|
|
38
|
+
restartPolicy: "no" | "unless-stopped" | "always";
|
|
39
|
+
}
|
|
40
|
+
export interface WhisperSettings {
|
|
41
|
+
imageTag: string;
|
|
42
|
+
model: WhisperModel;
|
|
43
|
+
language: string;
|
|
44
|
+
initialPrompt: string;
|
|
45
|
+
port: number;
|
|
46
|
+
advanced: AdvancedSettings;
|
|
47
|
+
}
|
|
48
|
+
export declare function defaultSettings(): WhisperSettings;
|
|
49
|
+
/**
|
|
50
|
+
* Merge raw plugin config over the defaults. Signal K does NOT seed schema
|
|
51
|
+
* defaults into saved configurations, and hand-edited config files can hold
|
|
52
|
+
* anything — every field is validated and falls back to its default.
|
|
53
|
+
* Guarantees `model` is never "auto" (see WHISPER_MODELS).
|
|
54
|
+
*/
|
|
55
|
+
export declare function applyDefaults(raw: unknown): WhisperSettings;
|
|
56
|
+
/** Maps the user-facing tag to the tag actually run: "auto" → pinned. */
|
|
57
|
+
export declare function resolveTag(requested: string): string;
|
|
58
|
+
/** True for plain numeric semver tags like "3.5.0" (update-check filter). */
|
|
59
|
+
export declare function isSemverTag(tag: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Pure, deterministic settings → ContainerConfig mapping. Called on every
|
|
62
|
+
* start/update; the `command` array is always present and stable so
|
|
63
|
+
* signalk-container's drift detection never recreate-loops.
|
|
64
|
+
*
|
|
65
|
+
* Networking: by default the Wyoming port is declared via
|
|
66
|
+
* `signalkAccessiblePorts` (published on host loopback on bare metal; wired
|
|
67
|
+
* to the right network on containerized Signal K). `bind: "0.0.0.0"`
|
|
68
|
+
* switches to an explicit all-interfaces port publish (for sharing the
|
|
69
|
+
* service with e.g. Home Assistant) — the two mechanisms must never be
|
|
70
|
+
* combined on the same port.
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildContainerConfig(settings: WhisperSettings, tag: string): ContainerConfig;
|
|
73
|
+
export declare const CONFIG_SCHEMA: {
|
|
74
|
+
readonly type: "object";
|
|
75
|
+
readonly properties: {
|
|
76
|
+
readonly model: {
|
|
77
|
+
readonly type: "string";
|
|
78
|
+
readonly title: "Whisper model";
|
|
79
|
+
readonly enum: readonly ["tiny-int8", "base-int8", "small-int8", "medium-int8", "tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium.en", "turbo"];
|
|
80
|
+
readonly default: "tiny-int8";
|
|
81
|
+
readonly description: string;
|
|
82
|
+
};
|
|
83
|
+
readonly language: {
|
|
84
|
+
readonly type: "string";
|
|
85
|
+
readonly title: "Language";
|
|
86
|
+
readonly default: "en";
|
|
87
|
+
readonly description: string;
|
|
88
|
+
};
|
|
89
|
+
readonly initialPrompt: {
|
|
90
|
+
readonly type: "string";
|
|
91
|
+
readonly title: "Initial prompt (vocabulary hint)";
|
|
92
|
+
readonly default: string;
|
|
93
|
+
readonly description: string;
|
|
94
|
+
};
|
|
95
|
+
readonly imageTag: {
|
|
96
|
+
readonly type: "string";
|
|
97
|
+
readonly title: "Image tag";
|
|
98
|
+
readonly default: "auto";
|
|
99
|
+
readonly description: string;
|
|
100
|
+
};
|
|
101
|
+
readonly port: {
|
|
102
|
+
readonly type: "number";
|
|
103
|
+
readonly title: "Host port";
|
|
104
|
+
readonly default: 10300;
|
|
105
|
+
readonly description: string;
|
|
106
|
+
};
|
|
107
|
+
readonly advanced: {
|
|
108
|
+
readonly type: "object";
|
|
109
|
+
readonly title: "Advanced";
|
|
110
|
+
readonly properties: {
|
|
111
|
+
readonly bind: {
|
|
112
|
+
readonly type: "string";
|
|
113
|
+
readonly title: "Bind address";
|
|
114
|
+
readonly enum: readonly ["127.0.0.1", "0.0.0.0"];
|
|
115
|
+
readonly default: "127.0.0.1";
|
|
116
|
+
readonly description: string;
|
|
117
|
+
};
|
|
118
|
+
readonly memoryLimit: {
|
|
119
|
+
readonly type: "string";
|
|
120
|
+
readonly title: "Memory limit";
|
|
121
|
+
readonly default: "1g";
|
|
122
|
+
readonly description: string;
|
|
123
|
+
};
|
|
124
|
+
readonly restartPolicy: {
|
|
125
|
+
readonly type: "string";
|
|
126
|
+
readonly title: "Restart policy";
|
|
127
|
+
readonly enum: readonly ["no", "unless-stopped", "always"];
|
|
128
|
+
readonly default: "unless-stopped";
|
|
129
|
+
readonly description: "Container runtime restart policy.";
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
export declare const UI_SCHEMA: {
|
|
136
|
+
readonly initialPrompt: {
|
|
137
|
+
readonly "ui:widget": "textarea";
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,eAAO,MAAM,SAAS,oBAAoB,CAAC;AAC3C,eAAO,MAAM,WAAW,0BAA0B,CAAC;AACnD,eAAO,MAAM,YAAY,QAAQ,CAAC;AAClC,2EAA2E;AAC3E,eAAO,MAAM,cAAc,YAAY,CAAC;AACxC,eAAO,MAAM,KAAK,4BAA4B,CAAC;AAC/C,4EAA4E;AAC5E,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAQ,CAAC;AAClC,eAAO,MAAM,iBAAiB,gCAAgC,CAAC;AAC/D,2EAA2E;AAC3E,eAAO,MAAM,aAAa,mDAAyC,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,mJAajB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,eAAe,QAIqB,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,IAAI,GAAG,gBAAgB,GAAG,QAAQ,CAAC;CACnD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,wBAAgB,eAAe,IAAI,eAAe,CAajD;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,CAkD3D;AAED,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,eAAe,EACzB,GAAG,EAAE,MAAM,GACV,eAAe,CA4BjB;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2FhB,CAAC;AAEX,eAAO,MAAM,SAAS;;;;CAIZ,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* signalk-whisper configuration: JSON schema, defaults, and the pure
|
|
3
|
+
* settings → ContainerConfig mapping consumed by signalk-container-helper.
|
|
4
|
+
*/
|
|
5
|
+
export const PLUGIN_ID = "signalk-whisper";
|
|
6
|
+
export const PLUGIN_NAME = "Whisper STT (Wyoming)";
|
|
7
|
+
export const SERVICE_TYPE = "asr";
|
|
8
|
+
/** Unprefixed container name; runs as `sk-whisper` on the host runtime. */
|
|
9
|
+
export const CONTAINER_NAME = "whisper";
|
|
10
|
+
export const IMAGE = "rhasspy/wyoming-whisper";
|
|
11
|
+
/** Pinned, tested upstream release; `imageTag: "auto"` resolves to this. */
|
|
12
|
+
export const PINNED_TAG = "3.5.0";
|
|
13
|
+
/**
|
|
14
|
+
* Container-side Wyoming port. The image bakes `--uri tcp://0.0.0.0:10300`
|
|
15
|
+
* into its entrypoint, so the container ALWAYS listens on 10300 internally.
|
|
16
|
+
*/
|
|
17
|
+
export const WYOMING_PORT = 10300;
|
|
18
|
+
export const NOTIFICATION_PATH = "notifications.voice.whisper";
|
|
19
|
+
/** First-start model download sizes surfaced in plugin status / README. */
|
|
20
|
+
export const DOWNLOAD_HINT = "tiny-int8 ≈ 43 MB, base-int8 ≈ 80 MB";
|
|
21
|
+
/**
|
|
22
|
+
* Models accepted by the `--model` flag. NEVER "auto": with the 3.5.0 image
|
|
23
|
+
* `--model auto --language en` silently switches to a ~0.6B-parameter
|
|
24
|
+
* sherpa/Parakeet backend and downloads hundreds of MB — a disaster on a
|
|
25
|
+
* boat server. int8 models are the recommended choice.
|
|
26
|
+
*/
|
|
27
|
+
export const WHISPER_MODELS = [
|
|
28
|
+
"tiny-int8",
|
|
29
|
+
"base-int8",
|
|
30
|
+
"small-int8",
|
|
31
|
+
"medium-int8",
|
|
32
|
+
"tiny",
|
|
33
|
+
"tiny.en",
|
|
34
|
+
"base",
|
|
35
|
+
"base.en",
|
|
36
|
+
"small",
|
|
37
|
+
"small.en",
|
|
38
|
+
"medium.en",
|
|
39
|
+
"turbo",
|
|
40
|
+
];
|
|
41
|
+
/**
|
|
42
|
+
* Default `--initial-prompt`: nautical vocabulary that biases Whisper toward
|
|
43
|
+
* sailing terms. The cheapest accuracy win available — user-editable.
|
|
44
|
+
*/
|
|
45
|
+
export const NAUTICAL_PROMPT = "Genoa, jib, mainsail, spinnaker, windlass, gybe, tack, halyard, winch, " +
|
|
46
|
+
"anchor chain, rode, bilge, galley, helm, autopilot, waypoint, knots, " +
|
|
47
|
+
"port, starboard, bow, stern, leeward, windward, reef, furl, " +
|
|
48
|
+
"log position, anchor alarm, engine, throttle.";
|
|
49
|
+
export function defaultSettings() {
|
|
50
|
+
return {
|
|
51
|
+
imageTag: "auto",
|
|
52
|
+
model: "tiny-int8",
|
|
53
|
+
language: "en",
|
|
54
|
+
initialPrompt: NAUTICAL_PROMPT,
|
|
55
|
+
port: WYOMING_PORT,
|
|
56
|
+
advanced: {
|
|
57
|
+
bind: "127.0.0.1",
|
|
58
|
+
memoryLimit: "1g",
|
|
59
|
+
restartPolicy: "unless-stopped",
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function isRecord(value) {
|
|
64
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Merge raw plugin config over the defaults. Signal K does NOT seed schema
|
|
68
|
+
* defaults into saved configurations, and hand-edited config files can hold
|
|
69
|
+
* anything — every field is validated and falls back to its default.
|
|
70
|
+
* Guarantees `model` is never "auto" (see WHISPER_MODELS).
|
|
71
|
+
*/
|
|
72
|
+
export function applyDefaults(raw) {
|
|
73
|
+
const defaults = defaultSettings();
|
|
74
|
+
if (!isRecord(raw))
|
|
75
|
+
return defaults;
|
|
76
|
+
const adv = isRecord(raw.advanced) ? raw.advanced : {};
|
|
77
|
+
const model = typeof raw.model === "string" &&
|
|
78
|
+
WHISPER_MODELS.includes(raw.model)
|
|
79
|
+
? raw.model
|
|
80
|
+
: defaults.model;
|
|
81
|
+
const language = typeof raw.language === "string" && raw.language.trim() !== ""
|
|
82
|
+
? raw.language.trim()
|
|
83
|
+
: defaults.language;
|
|
84
|
+
// Empty string is meaningful (disables --initial-prompt entirely).
|
|
85
|
+
const initialPrompt = typeof raw.initialPrompt === "string"
|
|
86
|
+
? raw.initialPrompt
|
|
87
|
+
: defaults.initialPrompt;
|
|
88
|
+
const imageTag = typeof raw.imageTag === "string" && raw.imageTag.trim() !== ""
|
|
89
|
+
? raw.imageTag.trim()
|
|
90
|
+
: defaults.imageTag;
|
|
91
|
+
const port = typeof raw.port === "number" &&
|
|
92
|
+
Number.isInteger(raw.port) &&
|
|
93
|
+
raw.port > 0 &&
|
|
94
|
+
raw.port <= 65535
|
|
95
|
+
? raw.port
|
|
96
|
+
: defaults.port;
|
|
97
|
+
const bind = adv.bind === "0.0.0.0" ? "0.0.0.0" : defaults.advanced.bind;
|
|
98
|
+
const memoryLimit = typeof adv.memoryLimit === "string" && adv.memoryLimit.trim() !== ""
|
|
99
|
+
? adv.memoryLimit.trim()
|
|
100
|
+
: defaults.advanced.memoryLimit;
|
|
101
|
+
const restartPolicy = adv.restartPolicy === "no" ||
|
|
102
|
+
adv.restartPolicy === "always" ||
|
|
103
|
+
adv.restartPolicy === "unless-stopped"
|
|
104
|
+
? adv.restartPolicy
|
|
105
|
+
: defaults.advanced.restartPolicy;
|
|
106
|
+
return {
|
|
107
|
+
imageTag,
|
|
108
|
+
model,
|
|
109
|
+
language,
|
|
110
|
+
initialPrompt,
|
|
111
|
+
port,
|
|
112
|
+
advanced: { bind, memoryLimit, restartPolicy },
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** Maps the user-facing tag to the tag actually run: "auto" → pinned. */
|
|
116
|
+
export function resolveTag(requested) {
|
|
117
|
+
return requested === "auto" ? PINNED_TAG : requested;
|
|
118
|
+
}
|
|
119
|
+
/** True for plain numeric semver tags like "3.5.0" (update-check filter). */
|
|
120
|
+
export function isSemverTag(tag) {
|
|
121
|
+
return /^\d+\.\d+\.\d+$/.test(tag);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Pure, deterministic settings → ContainerConfig mapping. Called on every
|
|
125
|
+
* start/update; the `command` array is always present and stable so
|
|
126
|
+
* signalk-container's drift detection never recreate-loops.
|
|
127
|
+
*
|
|
128
|
+
* Networking: by default the Wyoming port is declared via
|
|
129
|
+
* `signalkAccessiblePorts` (published on host loopback on bare metal; wired
|
|
130
|
+
* to the right network on containerized Signal K). `bind: "0.0.0.0"`
|
|
131
|
+
* switches to an explicit all-interfaces port publish (for sharing the
|
|
132
|
+
* service with e.g. Home Assistant) — the two mechanisms must never be
|
|
133
|
+
* combined on the same port.
|
|
134
|
+
*/
|
|
135
|
+
export function buildContainerConfig(settings, tag) {
|
|
136
|
+
const prompt = settings.initialPrompt.trim();
|
|
137
|
+
const command = [
|
|
138
|
+
"--model",
|
|
139
|
+
settings.model,
|
|
140
|
+
"--language",
|
|
141
|
+
settings.language,
|
|
142
|
+
...(prompt === "" ? [] : ["--initial-prompt", prompt]),
|
|
143
|
+
];
|
|
144
|
+
const config = {
|
|
145
|
+
image: IMAGE,
|
|
146
|
+
tag,
|
|
147
|
+
command,
|
|
148
|
+
// Model downloads land in /data; mounting the plugin's Signal K data
|
|
149
|
+
// dir there makes them survive container recreation (offline-first).
|
|
150
|
+
signalkDataMount: "/data",
|
|
151
|
+
restart: settings.advanced.restartPolicy,
|
|
152
|
+
resources: {
|
|
153
|
+
memory: settings.advanced.memoryLimit,
|
|
154
|
+
memorySwap: settings.advanced.memoryLimit,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
if (settings.advanced.bind === "0.0.0.0") {
|
|
158
|
+
config.ports = { [String(WYOMING_PORT)]: `0.0.0.0:${settings.port}` };
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
config.signalkAccessiblePorts = [WYOMING_PORT];
|
|
162
|
+
}
|
|
163
|
+
return config;
|
|
164
|
+
}
|
|
165
|
+
export const CONFIG_SCHEMA = {
|
|
166
|
+
type: "object",
|
|
167
|
+
properties: {
|
|
168
|
+
model: {
|
|
169
|
+
type: "string",
|
|
170
|
+
title: "Whisper model",
|
|
171
|
+
enum: [...WHISPER_MODELS],
|
|
172
|
+
default: "tiny-int8",
|
|
173
|
+
description: "Speech-recognition model. The int8 models are recommended: " +
|
|
174
|
+
"tiny-int8 fits a Pi 4, base-int8 is noticeably more accurate on a " +
|
|
175
|
+
"Pi 5 / x86 box. Larger models are slower and use much more RAM — " +
|
|
176
|
+
"use the signalk-wyoming webapp's Test screen latency display to " +
|
|
177
|
+
"guide upgrades. Changing the model downloads it on first use " +
|
|
178
|
+
"(tiny-int8 ≈ 43 MB, base-int8 ≈ 80 MB).",
|
|
179
|
+
},
|
|
180
|
+
language: {
|
|
181
|
+
type: "string",
|
|
182
|
+
title: "Language",
|
|
183
|
+
default: "en",
|
|
184
|
+
description: "Spoken language code (e.g. en, de, fr). 'auto' enables per-utterance " +
|
|
185
|
+
"language detection but costs both speed and accuracy on the small " +
|
|
186
|
+
"models — set it explicitly if you can.",
|
|
187
|
+
},
|
|
188
|
+
initialPrompt: {
|
|
189
|
+
type: "string",
|
|
190
|
+
title: "Initial prompt (vocabulary hint)",
|
|
191
|
+
default: NAUTICAL_PROMPT,
|
|
192
|
+
description: "Text passed to Whisper as --initial-prompt to bias recognition " +
|
|
193
|
+
"toward your vocabulary. Ships with a nautical word list — add your " +
|
|
194
|
+
"vessel name, local port names, and boat-specific gear. Leave empty " +
|
|
195
|
+
"to disable.",
|
|
196
|
+
},
|
|
197
|
+
imageTag: {
|
|
198
|
+
type: "string",
|
|
199
|
+
title: "Image tag",
|
|
200
|
+
default: "auto",
|
|
201
|
+
description: `Docker image tag for ${IMAGE}. 'auto' runs the pinned, tested ` +
|
|
202
|
+
`release (${PINNED_TAG}) and follows this plugin's updates. Set an ` +
|
|
203
|
+
"explicit tag only if you need to pin a different upstream version.",
|
|
204
|
+
},
|
|
205
|
+
port: {
|
|
206
|
+
type: "number",
|
|
207
|
+
title: "Host port",
|
|
208
|
+
default: WYOMING_PORT,
|
|
209
|
+
description: "Host TCP port for the Wyoming service — only used with 'Bind " +
|
|
210
|
+
"address' 0.0.0.0, where the service is published on exactly this " +
|
|
211
|
+
"port. With the default loopback networking this setting is " +
|
|
212
|
+
"ignored: signalk-container assigns the host port automatically " +
|
|
213
|
+
"(normally 10300, the next free port if that is taken).",
|
|
214
|
+
},
|
|
215
|
+
advanced: {
|
|
216
|
+
type: "object",
|
|
217
|
+
title: "Advanced",
|
|
218
|
+
properties: {
|
|
219
|
+
bind: {
|
|
220
|
+
type: "string",
|
|
221
|
+
title: "Bind address",
|
|
222
|
+
enum: ["127.0.0.1", "0.0.0.0"],
|
|
223
|
+
default: "127.0.0.1",
|
|
224
|
+
description: "127.0.0.1 (default) keeps whisper reachable only from this " +
|
|
225
|
+
"machine — the signalk-wyoming orchestrator is its only " +
|
|
226
|
+
"intended consumer. 0.0.0.0 publishes it on all interfaces so " +
|
|
227
|
+
"other systems (e.g. Home Assistant) can share it. Wyoming has " +
|
|
228
|
+
"no authentication: only expose it on trusted networks (see the " +
|
|
229
|
+
"README security notes).",
|
|
230
|
+
},
|
|
231
|
+
memoryLimit: {
|
|
232
|
+
type: "string",
|
|
233
|
+
title: "Memory limit",
|
|
234
|
+
default: "1g",
|
|
235
|
+
description: "Hard container memory cap (docker syntax, e.g. 1g, 1536m). " +
|
|
236
|
+
"Swap is capped to the same value. Keeps a misbehaving model " +
|
|
237
|
+
"from taking down the boat server.",
|
|
238
|
+
},
|
|
239
|
+
restartPolicy: {
|
|
240
|
+
type: "string",
|
|
241
|
+
title: "Restart policy",
|
|
242
|
+
enum: ["no", "unless-stopped", "always"],
|
|
243
|
+
default: "unless-stopped",
|
|
244
|
+
description: "Container runtime restart policy.",
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
export const UI_SCHEMA = {
|
|
251
|
+
initialPrompt: {
|
|
252
|
+
"ui:widget": "textarea",
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,CAAC,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAC3C,MAAM,CAAC,MAAM,WAAW,GAAG,uBAAuB,CAAC;AACnD,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC;AAClC,2EAA2E;AAC3E,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC;AACxC,MAAM,CAAC,MAAM,KAAK,GAAG,yBAAyB,CAAC;AAC/C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC;AAClC;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC;AAClC,MAAM,CAAC,MAAM,iBAAiB,GAAG,6BAA6B,CAAC;AAC/D,2EAA2E;AAC3E,MAAM,CAAC,MAAM,aAAa,GAAG,sCAAsC,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,WAAW;IACX,WAAW;IACX,YAAY;IACZ,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACN,SAAS;IACT,OAAO;IACP,UAAU;IACV,WAAW;IACX,OAAO;CACC,CAAC;AAIX;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAC1B,yEAAyE;IACzE,uEAAuE;IACvE,8DAA8D;IAC9D,+CAA+C,CAAC;AAiBlD,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,WAAW;QAClB,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,eAAe;QAC9B,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE;YACR,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,gBAAgB;SAChC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvD,MAAM,KAAK,GACT,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;QAC5B,cAAoC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;QACvD,CAAC,CAAE,GAAG,CAAC,KAAsB;QAC7B,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IACrB,MAAM,QAAQ,GACZ,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;QAC5D,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;QACrB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACxB,mEAAmE;IACnE,MAAM,aAAa,GACjB,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ;QACnC,CAAC,CAAC,GAAG,CAAC,aAAa;QACnB,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;IAC7B,MAAM,QAAQ,GACZ,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;QAC5D,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;QACrB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACxB,MAAM,IAAI,GACR,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAC5B,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;QAC1B,GAAG,CAAC,IAAI,GAAG,CAAC;QACZ,GAAG,CAAC,IAAI,IAAI,KAAK;QACf,CAAC,CAAC,GAAG,CAAC,IAAI;QACV,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;IACpB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;IACzE,MAAM,WAAW,GACf,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE;QAClE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE;QACxB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;IACpC,MAAM,aAAa,GACjB,GAAG,CAAC,aAAa,KAAK,IAAI;QAC1B,GAAG,CAAC,aAAa,KAAK,QAAQ;QAC9B,GAAG,CAAC,aAAa,KAAK,gBAAgB;QACpC,CAAC,CAAC,GAAG,CAAC,aAAa;QACnB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;IAEtC,OAAO;QACL,QAAQ;QACR,KAAK;QACL,QAAQ;QACR,aAAa;QACb,IAAI;QACJ,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE;KAC/C,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAyB,EACzB,GAAW;IAEX,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IAC7C,MAAM,OAAO,GAAG;QACd,SAAS;QACT,QAAQ,CAAC,KAAK;QACd,YAAY;QACZ,QAAQ,CAAC,QAAQ;QACjB,GAAG,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;KACvD,CAAC;IACF,MAAM,MAAM,GAAoB;QAC9B,KAAK,EAAE,KAAK;QACZ,GAAG;QACH,OAAO;QACP,qEAAqE;QACrE,qEAAqE;QACrE,gBAAgB,EAAE,OAAO;QACzB,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,aAAa;QACxC,SAAS,EAAE;YACT,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,WAAW;YACrC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,WAAW;SAC1C;KACF,CAAC;IACF,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACzC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,WAAW,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,sBAAsB,GAAG,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,CAAC,GAAG,cAAc,CAAC;YACzB,OAAO,EAAE,WAAW;YACpB,WAAW,EACT,6DAA6D;gBAC7D,oEAAoE;gBACpE,mEAAmE;gBACnE,kEAAkE;gBAClE,+DAA+D;gBAC/D,yCAAyC;SAC5C;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,IAAI;YACb,WAAW,EACT,uEAAuE;gBACvE,oEAAoE;gBACpE,wCAAwC;SAC3C;QACD,aAAa,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,kCAAkC;YACzC,OAAO,EAAE,eAAe;YACxB,WAAW,EACT,iEAAiE;gBACjE,qEAAqE;gBACrE,qEAAqE;gBACrE,aAAa;SAChB;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,MAAM;YACf,WAAW,EACT,wBAAwB,KAAK,mCAAmC;gBAChE,YAAY,UAAU,8CAA8C;gBACpE,oEAAoE;SACvE;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,YAAY;YACrB,WAAW,EACT,+DAA+D;gBAC/D,mEAAmE;gBACnE,6DAA6D;gBAC7D,iEAAiE;gBACjE,wDAAwD;SAC3D;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,UAAU;YACjB,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,cAAc;oBACrB,IAAI,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;oBAC9B,OAAO,EAAE,WAAW;oBACpB,WAAW,EACT,6DAA6D;wBAC7D,yDAAyD;wBACzD,+DAA+D;wBAC/D,gEAAgE;wBAChE,iEAAiE;wBACjE,yBAAyB;iBAC5B;gBACD,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,cAAc;oBACrB,OAAO,EAAE,IAAI;oBACb,WAAW,EACT,6DAA6D;wBAC7D,8DAA8D;wBAC9D,mCAAmC;iBACtC;gBACD,aAAa,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,gBAAgB;oBACvB,IAAI,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC;oBACxC,OAAO,EAAE,gBAAgB;oBACzB,WAAW,EAAE,mCAAmC;iBACjD;aACF;SACF;KACF;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,aAAa,EAAE;QACb,WAAW,EAAE,UAAU;KACxB;CACO,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* signalk-whisper — Whisper speech-to-text (Wyoming protocol) for Signal K.
|
|
3
|
+
*
|
|
4
|
+
* Runs rhasspy/wyoming-whisper in a container managed via signalk-container
|
|
5
|
+
* (through signalk-container-helper), gates readiness on a Wyoming
|
|
6
|
+
* `describe` handshake, health-checks it, and advertises the service on the
|
|
7
|
+
* shared `wyoming-service` PropertyValues channel for the signalk-wyoming
|
|
8
|
+
* orchestrator (or any other consumer) to discover.
|
|
9
|
+
*/
|
|
10
|
+
import type { Plugin, ServerAPI } from "@signalk/server-api";
|
|
11
|
+
import { ServiceRunner, type RunnerTiming } from "./service.js";
|
|
12
|
+
export type { RunnerTiming };
|
|
13
|
+
export { ServiceRunner };
|
|
14
|
+
export default function createPlugin(app: ServerAPI): Plugin;
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAc7D,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEhE,YAAY,EAAE,YAAY,EAAE,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;AA6BzB,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAiI3D"}
|