@happyvertical/smrt-svelte 0.55.5 → 0.55.7
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/AGENTS.md +17 -2
- package/README.md +83 -4
- package/agents/workspace.md +202 -5
- package/dist/browser-ai/adapters/stt/dictation-source.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/dictation-source.js +8 -2
- package/dist/browser-ai/adapters/stt/factory.d.ts +6 -3
- package/dist/browser-ai/adapters/stt/factory.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/factory.js +19 -9
- package/dist/browser-ai/adapters/stt/index.d.ts +3 -1
- package/dist/browser-ai/adapters/stt/index.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/index.js +3 -1
- package/dist/browser-ai/adapters/stt/local-speech-model.d.ts +111 -0
- package/dist/browser-ai/adapters/stt/local-speech-model.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech-model.js +377 -0
- package/dist/browser-ai/adapters/stt/local-speech.d.ts +82 -0
- package/dist/browser-ai/adapters/stt/local-speech.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech.js +317 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.d.ts +2 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.js +32 -0
- package/dist/browser-ai/adapters/stt/transformers-env.d.ts +8 -0
- package/dist/browser-ai/adapters/stt/transformers-env.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/transformers-env.js +17 -0
- package/dist/browser-ai/adapters/stt/types.d.ts +54 -9
- package/dist/browser-ai/adapters/stt/types.d.ts.map +1 -1
- package/dist/browser-ai/capabilities/speech-probe.d.ts +29 -0
- package/dist/browser-ai/capabilities/speech-probe.d.ts.map +1 -0
- package/dist/browser-ai/capabilities/speech-probe.js +19 -0
- package/dist/browser-ai/core/errors.d.ts +9 -0
- package/dist/browser-ai/core/errors.d.ts.map +1 -1
- package/dist/browser-ai/core/errors.js +12 -0
- package/dist/browser-ai/index.d.ts +1 -0
- package/dist/browser-ai/index.d.ts.map +1 -1
- package/dist/browser-ai/index.js +1 -0
- package/dist/components/app/AppShell.svelte +587 -33
- package/dist/components/app/AppShell.svelte.d.ts +75 -4
- package/dist/components/app/AppShell.svelte.d.ts.map +1 -1
- package/dist/components/app/DockToggles.svelte +0 -1
- package/dist/components/app/dock-toggle.d.ts +7 -1
- package/dist/components/app/dock-toggle.d.ts.map +1 -1
- package/dist/components/app/index.d.ts +2 -1
- package/dist/components/app/index.d.ts.map +1 -1
- package/dist/components/app/slot-item.d.ts +21 -0
- package/dist/components/app/slot-item.d.ts.map +1 -0
- package/dist/components/app/slot-item.js +1 -0
- package/dist/components/audit/AuditList.svelte +51 -10
- package/dist/components/audit/AuditList.svelte.d.ts +13 -1
- package/dist/components/audit/AuditList.svelte.d.ts.map +1 -1
- package/dist/components/audit/RecordHistory.svelte +168 -10
- package/dist/components/audit/RecordHistory.svelte.d.ts +11 -1
- package/dist/components/audit/RecordHistory.svelte.d.ts.map +1 -1
- package/dist/components/audit/index.d.ts +1 -1
- package/dist/components/audit/index.d.ts.map +1 -1
- package/dist/components/audit/types.d.ts +18 -0
- package/dist/components/audit/types.d.ts.map +1 -1
- package/dist/components/forms/AddressInput.svelte +2 -15
- package/dist/components/forms/AddressInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/DateRangeInput.svelte +2 -15
- package/dist/components/forms/DateRangeInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/DateTimeInput.svelte +8 -15
- package/dist/components/forms/DateTimeInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/MeasurementInput.svelte +2 -15
- package/dist/components/forms/MeasurementInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/MoneyInput.svelte +8 -25
- package/dist/components/forms/MoneyInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/NumberInput.svelte +7 -15
- package/dist/components/forms/NumberInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/PhoneInput.svelte +7 -15
- package/dist/components/forms/PhoneInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/SelectInput.svelte +34 -40
- package/dist/components/forms/SelectInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/TextInput.svelte +20 -37
- package/dist/components/forms/TextInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/TextareaInput.svelte +19 -35
- package/dist/components/forms/TextareaInput.svelte.d.ts.map +1 -1
- package/dist/components/sortable/Sortable.svelte +6 -33
- package/dist/components/sortable/Sortable.svelte.d.ts.map +1 -1
- package/dist/components/sortable/announce.d.ts +5 -0
- package/dist/components/sortable/announce.d.ts.map +1 -0
- package/dist/components/sortable/announce.js +33 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte +424 -58
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts +27 -2
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellBrand.svelte +86 -0
- package/dist/components/workspace/admin-shell/ShellBrand.svelte.d.ts +18 -0
- package/dist/components/workspace/admin-shell/ShellBrand.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte +77 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte.d.ts +26 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte +88 -16
- package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte +531 -0
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts +26 -0
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte +57 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte.d.ts +22 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte +290 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts +32 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte +67 -2
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts +8 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout-controller.svelte.d.ts +67 -0
- package/dist/components/workspace/admin-shell/layout-controller.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout-controller.svelte.js +129 -1
- package/dist/components/workspace/admin-shell/layout.d.ts +122 -0
- package/dist/components/workspace/admin-shell/layout.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout.js +410 -10
- package/dist/components/workspace/admin-shell/settings.js +4 -4
- package/dist/components/workspace/admin-shell/shell-icons.d.ts +45 -0
- package/dist/components/workspace/admin-shell/shell-icons.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/shell-icons.js +66 -0
- package/dist/components/workspace/admin-shell/slot-labels.d.ts +33 -0
- package/dist/components/workspace/admin-shell/slot-labels.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/slot-labels.js +33 -0
- package/dist/components/workspace/admin-shell/slots.d.ts +50 -0
- package/dist/components/workspace/admin-shell/slots.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/slots.js +77 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts +35 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/state.svelte.js +111 -0
- package/dist/components/workspace/admin-shell/types.d.ts +101 -1
- package/dist/components/workspace/admin-shell/types.d.ts.map +1 -1
- package/dist/components/workspace/index.d.ts +9 -2
- package/dist/components/workspace/index.d.ts.map +1 -1
- package/dist/components/workspace/index.js +6 -0
- package/dist/i18n/strings.workspace.d.ts +49 -0
- package/dist/i18n/strings.workspace.d.ts.map +1 -1
- package/dist/i18n/strings.workspace.js +49 -0
- package/package.json +30 -19
- package/dist/browser-ai/adapters/stt/whisper-wasm.d.ts +0 -51
- package/dist/browser-ai/adapters/stt/whisper-wasm.d.ts.map +0 -1
- package/dist/browser-ai/adapters/stt/whisper-wasm.js +0 -380
package/AGENTS.md
CHANGED
|
@@ -205,7 +205,22 @@ for a data-surface one — for exactly the component's lifetime.
|
|
|
205
205
|
|
|
206
206
|
- **Preload strategies**: `none`, `eager`, `idle` (recommended), `on-visible`
|
|
207
207
|
- **Warm client cache**: module-level Map survives navigation/remounts -- avoids re-downloading WASM/models
|
|
208
|
-
- **Adapters**: STT (browser-speech, whisper-cpp, whisper-wasm), TTS (browser-synthesis), LLM (webllm, transformers-llm)
|
|
208
|
+
- **Adapters**: STT (browser-speech, whisper-cpp, whisper-local = alias whisper-wasm), TTS (browser-synthesis), LLM (webllm, transformers-llm)
|
|
209
|
+
- **On-device speech** (`whisper-local` = alias `whisper-wasm`, and `moonshine`): thin adapters over
|
|
210
|
+
`@happyvertical/speech/local` (`LocalTranscriber`, or its worker host `serveLocalTranscriber`).
|
|
211
|
+
Push-to-talk (record on `start()`, transcribe on `stop()`, one final result) plus `transcribePcm()`
|
|
212
|
+
for smrt-ui's hands-free mode. Default `onnx-community/whisper-tiny.en` q8 (~45 MB, Cache
|
|
213
|
+
Storage); `model: 'moonshine-tiny'` (~32 MB) / `'moonshine-base'` (~67 MB) or any HF id
|
|
214
|
+
(`LOCAL_SPEECH_MODELS`); WebGPU else single-thread WASM (no COOP/COEP needed). The package never
|
|
215
|
+
imports the peers: a host passes `createWorker` (build it from
|
|
216
|
+
`@happyvertical/smrt-svelte/browser-ai/whisper-worker?worker`, alias `speech-worker`, the one module
|
|
217
|
+
that imports `@happyvertical/speech/local` and `@huggingface/transformers` statically) plus
|
|
218
|
+
`loadSpeech: () => import('@happyvertical/speech/local')`, or `loadModule` for the page thread.
|
|
219
|
+
`createLocalSpeechModel()` (alias `createWhisperLocalModel()`) / `adapter.model` is the consent API
|
|
220
|
+
(`estimateSize`, `isCached`, `load({ onProgress, signal })` with `downloading` -> `extracting` ->
|
|
221
|
+
`complete`); share it via `modelHandle`. English-only handling of `language`/`task` lives in the speech
|
|
222
|
+
package. `probeBrowserSpeech()` -> `works | missing | unreliable` (no network, no mic prompt)
|
|
223
|
+
decides whether to offer it. Sources set `stopTimeoutMs` so `Dictation` waits for the transcription.
|
|
209
224
|
- Cache API: `getCachedSTT()`, `getCachedTTS()`, `getCachedLLM()`, `getCacheStats()`, `clearAllCaches()`
|
|
210
225
|
- **Inference backends (browser-ai)**: two `@happyvertical/smrt-web/ai` `InferenceBackend`s, both
|
|
211
226
|
`kind: 'local'`, both refusing `tool`/`function` messages, non-string content, `tool_calls` and
|
|
@@ -258,4 +273,4 @@ for a data-surface one — for exactly the component's lifetime.
|
|
|
258
273
|
- `@happyvertical/smrt-ui` (UI runtime: primitives, theme system, i18n client, module registry) is a hard `dependency`. The agent-admin shells that used to type against `@happyvertical/smrt-agents/ui` moved to `@happyvertical/smrt-agents/svelte` (#1589), so `smrt-agents` is no longer a dependency here — this drops smrt-svelte below smrt-agents in the package DAG.
|
|
259
274
|
- `@happyvertical/smrt-languages` is a hard `dependency` (not an optional peer): the Node-only `/i18n/server` subpath imports its resolver. The browser bundle still excludes it — the client `/i18n` layer never imports the languages root, so it tree-shakes out.
|
|
260
275
|
- `@happyvertical/logger` (SDK) is a `dependency` — the console logger used for voice/AI error reporting in the form components. Consume it **only** through `src/internal/logger.ts`, never `createLogger()` at module scope: `createLogger()` reads `HAVE_LOGGER_LEVEL` from `process.env`, so a top-level call throws `ReferenceError: process is not defined` in the browser and kills client-side hydration under `vite dev` (prod builds tree-shake/define it away, so this only bites in dev). The `internal/logger` wrapper constructs the logger lazily and falls back to a bare `ConsoleLogger` when `process.env` is absent, keeping this browser-reachable module (imported by `Provider` + the form primitives) safe.
|
|
261
|
-
- Peer (all optional): `svelte` >=5.18.2, plus the browser-AI engines (`@huggingface/transformers`, `@mlc-ai/web-llm`, `@remotion/whisper-web
|
|
276
|
+
- Peer (all optional): `svelte` >=5.18.2, plus the browser-AI engines (`@happyvertical/speech`, `@huggingface/transformers`, `@mlc-ai/web-llm`, `@remotion/whisper-web`) and `chrono-node`.
|
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ items that share Board's drag engine. `AppShell` lets users customize their
|
|
|
40
40
|
shell: pass `layout` and `onlayoutchange` to own persistence (for example in an
|
|
41
41
|
exported app blueprint), or neither to store it in the user's settings. Mount
|
|
42
42
|
`ShellLayoutEditor` (from `/app` or `/workspace`) on a settings page, and call
|
|
43
|
-
`useShellLayout()` to make the same changes from code or an assistant. See
|
|
43
|
+
`useShellLayout()` to make the same changes from code or an assistant. Users can rename sections and individual navigation entries (`items`, `renameItem`), hide section titles, and create or delete their own sections. See
|
|
44
44
|
`agents/workspace.md`; the pure `ShellLayout` model is published without Svelte
|
|
45
45
|
as `@happyvertical/smrt-svelte/workspace/layout`.
|
|
46
46
|
|
|
@@ -50,6 +50,16 @@ as `@happyvertical/smrt-svelte/workspace/layout`.
|
|
|
50
50
|
</AppShell>
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
Opt in to editing the real shell in place with `layoutEditing` on `AppShell`: a
|
|
54
|
+
pencil toggle ("Edit layout", highlighted while editing; press again or Escape to exit) joins the header (as does the app title, a movable
|
|
55
|
+
`item:brand` in `header.start`), and while on, every slot is a
|
|
56
|
+
labelled drop zone, shell items and navigation get grips (drag, or Space and
|
|
57
|
+
arrow keys), section headings get icon overlays and a floating toolbar, and
|
|
58
|
+
hidden regions show as strips. Apps add per-section icon buttons (an Options
|
|
59
|
+
gear, Help) with `sectionActions`; pass `layoutEditing={{ floating: true }}` to pin the
|
|
60
|
+
toggle in the top-right corner instead of the header; `useShellLayout()` exposes `editing` and
|
|
61
|
+
`setEditing`. See `agents/workspace.md`.
|
|
62
|
+
|
|
53
63
|
## Installation
|
|
54
64
|
|
|
55
65
|
```bash
|
|
@@ -288,6 +298,60 @@ bind legacy name-based cleanup to registrations made by that caller, so
|
|
|
288
298
|
overlapping same-name fields can unmount in either order without retaining a
|
|
289
299
|
detached control.
|
|
290
300
|
|
|
301
|
+
### Voice typing where the browser cannot (on-device Whisper and Moonshine)
|
|
302
|
+
|
|
303
|
+
Browsers differ on speech recognition: Chrome and Safari have it, Firefox does
|
|
304
|
+
not, and Brave has the API without a speech service behind it. `probeBrowserSpeech()`
|
|
305
|
+
says which you have (`'works' | 'missing' | 'unreliable'`) without a network
|
|
306
|
+
call or a microphone prompt. For the last two, offer a one-time model download
|
|
307
|
+
and dictate with a speech model running in the browser (WebGPU where available,
|
|
308
|
+
single-thread WASM otherwise; no cross-origin isolation needed). The engine is
|
|
309
|
+
`@happyvertical/speech/local` (an optional peer, `>=0.102.5`, as is
|
|
310
|
+
`@huggingface/transformers`).
|
|
311
|
+
|
|
312
|
+
| `model` | Size | Notes |
|
|
313
|
+
| --- | --- | --- |
|
|
314
|
+
| `moonshine-tiny` (`onnx-community/moonshine-tiny-ONNX`) | ~32 MB | English, fastest: best for live dictation |
|
|
315
|
+
| `moonshine-base` (`onnx-community/moonshine-base-ONNX`) | ~67 MB | English, more accurate |
|
|
316
|
+
| `whisper-tiny.en` (default) | ~45 MB | English |
|
|
317
|
+
| `whisper-base.en` / `whisper-small.en` | ~85 / ~260 MB | English |
|
|
318
|
+
| any Hugging Face id, e.g. `onnx-community/whisper-base` | varies | multilingual Whisper |
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
import {
|
|
322
|
+
createLocalSpeechModel,
|
|
323
|
+
createSttDictationSource,
|
|
324
|
+
probeBrowserSpeech,
|
|
325
|
+
} from '@happyvertical/smrt-svelte/browser-ai';
|
|
326
|
+
// The worker is the one module that imports the optional peers statically,
|
|
327
|
+
// so only apps that build it bundle them.
|
|
328
|
+
import SpeechWorker from '@happyvertical/smrt-svelte/browser-ai/whisper-worker?worker';
|
|
329
|
+
|
|
330
|
+
if ((await probeBrowserSpeech()) !== 'works') {
|
|
331
|
+
const model = createLocalSpeechModel({
|
|
332
|
+
model: 'moonshine-tiny',
|
|
333
|
+
createWorker: () => new SpeechWorker(),
|
|
334
|
+
loadSpeech: () => import('@happyvertical/speech/local'),
|
|
335
|
+
});
|
|
336
|
+
model.estimateSize(); // ~32 MB, for the consent text
|
|
337
|
+
await model.isCached(); // already downloaded on this device?
|
|
338
|
+
await model.load({ onProgress, signal }); // downloading -> extracting ("Getting ready") -> complete; abort() cancels
|
|
339
|
+
const dictation = createSttDictationSource({ type: 'moonshine', modelHandle: model });
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
`createWhisperLocalModel`, `{ type: 'whisper-local' }` and the `whisper-wasm`
|
|
344
|
+
alias keep working. Without `createWorker` the model runs on the page's thread
|
|
345
|
+
and `loadModule: () => import('@huggingface/transformers')` supplies the
|
|
346
|
+
runtime. With a worker, `device` and `dtype` are the worker entry's (`auto`
|
|
347
|
+
and `q8`).
|
|
348
|
+
|
|
349
|
+
Push-to-talk: the microphone records until stopped, then one final result is
|
|
350
|
+
emitted. For hands-free dictation (each sentence written down when the speaker
|
|
351
|
+
pauses) give smrt-ui's `Dictation` `mode: 'hands-free'` and
|
|
352
|
+
`createHandsFreeCapture`; these adapters' `transcribePcm()` writes down each
|
|
353
|
+
utterance. English-only models (`*.en`, Moonshine) ignore a requested language.
|
|
354
|
+
|
|
291
355
|
### Form Components
|
|
292
356
|
|
|
293
357
|
```svelte
|
|
@@ -496,6 +560,12 @@ keys the shell renders exactly as before.
|
|
|
496
560
|
focus (unless something inside already has it) and returns it on close;
|
|
497
561
|
Escape or a scrim click closes it, sliding it back out as the scrim fades
|
|
498
562
|
(no motion under `prefers-reduced-motion`). Resizing applies only while docked.
|
|
563
|
+
- **Railless edges**: `rail: false` gives a side edge no rail (no tool buttons, open or closed); closed, it takes
|
|
564
|
+
no space and renders nothing to see or tab to, and opens from elsewhere (a
|
|
565
|
+
header dock toggle, `useShellDock()`). Pair it with `presentation: 'overlay'`
|
|
566
|
+
for a chat that slides over the page. Layout edit mode leaves a railless edge
|
|
567
|
+
as it is (closed stays closed) and, while editing, shows a small "Open
|
|
568
|
+
<tool>" tab on the shell's right edge when it has content.
|
|
499
569
|
- **Kept panels**: `keepMounted: true` keeps a collapsed edge's panel content
|
|
500
570
|
(`appPanel`, `tenantPanel`, the focus panel, `systemPanel`) mounted with the
|
|
501
571
|
`hidden` attribute instead of unmounting it, so component state (a chat
|
|
@@ -537,7 +607,7 @@ importable, even if it appears in `dist/`.
|
|
|
537
607
|
| `@happyvertical/smrt-svelte/forms` | Form inputs (TextInput, Select, MoneyInput, DateTimeInput, Toggle, etc.) |
|
|
538
608
|
| `@happyvertical/smrt-svelte/settings` | Server-paged settings search, selection, and list/detail layout (`SettingsCatalog`, `paginateSettingsCatalog`) |
|
|
539
609
|
| `@happyvertical/smrt-svelte/workspace` | AdminShell, ShellState, tenant nav, focus tools, settings, activities, and system/app panels |
|
|
540
|
-
| `@happyvertical/smrt-svelte/app` | `AppShell` (Provider + themes + AdminShell + nav/dock slots, `dockToggles` header
|
|
610
|
+
| `@happyvertical/smrt-svelte/app` | `AppShell` (Provider + themes + AdminShell + nav/dock slots, `dockToggles` buttons and host `slots` for the header/footer/sidebar regions), `OwnerSetupForm` (first-run owner setup), `ShellSettingsPage`, `RuntimeDiagnosticsWebMcp` |
|
|
541
611
|
| `@happyvertical/smrt-svelte/app/runtime-diagnostics` | Svelte-free diagnostics WebMCP registration and its tool name/endpoint constants, importable from server routes |
|
|
542
612
|
| `@happyvertical/smrt-svelte/workspace/legacy` | Opt-in ToolsDock compatibility surface for applications migrating to AdminShell |
|
|
543
613
|
| `@happyvertical/smrt-svelte/workspace/server` | Server-side workspace helpers (Node only) |
|
|
@@ -671,8 +741,10 @@ updates retain their existing behavior.
|
|
|
671
741
|
|
|
672
742
|
Use `shell.setPanelState(edge, 'hidden' | 'collapsed' | 'expanded')` to persist
|
|
673
743
|
runtime panel preferences; app-configured hidden edges remain unavailable.
|
|
674
|
-
AdminShell
|
|
675
|
-
(`
|
|
744
|
+
AdminShell's edge toggle buttons and WASD hotkeys are opt-in via `edgeToggles`
|
|
745
|
+
(default `false`: regions lay out inline; pass `true`, or a per-edge map, to
|
|
746
|
+
keep the drop-down behaviour; `showTenantToggle` is a deprecated alias for
|
|
747
|
+
`edgeToggles.left`), a Menu opener in narrow layouts, and the
|
|
676
748
|
system toggle alongside a custom `systemBar` that has a `systemPanel` to open
|
|
677
749
|
(a `systemBar` with no `systemPanel` owns the bottom band and draws no toggle). Closed narrow drawers are inert;
|
|
678
750
|
opening focuses the first control, and closing or Escape restores the opener.
|
|
@@ -688,6 +760,13 @@ canonical 48px target; omit density to inherit the theme, or choose
|
|
|
688
760
|
`"comfortable"`. Account menus in the shell app bar open below the bar so the
|
|
689
761
|
existing footer's default placement stays reachable on narrow screens.
|
|
690
762
|
|
|
763
|
+
Sections-only navigation: pass `navMode="sections"` to `AppShell` and give
|
|
764
|
+
each `ShellNavGroup` an `icon` and `href`; the sidebar then lists only the
|
|
765
|
+
sections, and the section's page renders its entries with `ShellSectionMenu`
|
|
766
|
+
(`meta`/`actions` snippets for counts and "New ..." links). In layout edit mode
|
|
767
|
+
the menu rows get grip, rename and hide controls, and the sidebar's section
|
|
768
|
+
toolbar gets an icon picker (`useShellLayout().setSectionIcon`).
|
|
769
|
+
|
|
691
770
|
`TenantNav` accepts optional `groups: ShellNavGroup[]` (`{ heading, items }`)
|
|
692
771
|
next to its existing flat `items`. Each group has a labelled `role="group"` and
|
|
693
772
|
native disclosure summary; keyboard and touch users can collapse it even in the
|
package/agents/workspace.md
CHANGED
|
@@ -83,6 +83,140 @@ and touch input across mobile widths and desktop panel-state combinations.
|
|
|
83
83
|
|
|
84
84
|
See `src/components/workspace/MIGRATION.md` for the old-to-new concept map.
|
|
85
85
|
|
|
86
|
+
### Regions and slots
|
|
87
|
+
|
|
88
|
+
Four regions map to the existing edges (ids and `ShellLayout.panels` keys are
|
|
89
|
+
unchanged): Header (`top`), Left sidebar (`left`), Right sidebar (`right`),
|
|
90
|
+
Footer (`bottom`). Default labels are those names; override via `config`.
|
|
91
|
+
`AdminShell`/`AppShell` take `slots?: Partial<Record<ShellSlot, Snippet>>`
|
|
92
|
+
(`ShellSlot` from `./workspace`): `header.start|center|end`,
|
|
93
|
+
`footer.start|center|end`, `leftSidebar.header|footer`,
|
|
94
|
+
`rightSidebar.header|footer`. Header/footer slots sit in the bar (start after
|
|
95
|
+
the brand/menu opener, end after the account), sidebar header sits above and
|
|
96
|
+
footer below the sidebar's main area. Defaults: brand/title/menu opener/account
|
|
97
|
+
stay where they were (`header.start`/`header.end` areas), `tenantFooter` stays
|
|
98
|
+
the left sidebar footer, `dockToggles` default to `header.end`. There is no
|
|
99
|
+
separate header row.
|
|
100
|
+
|
|
101
|
+
Fallback when a slot's region is hidden (or a sidebar is collapsed), first
|
|
102
|
+
visible wins (`slotFallbackChain`): header.X -> leftSidebar.header ->
|
|
103
|
+
rightSidebar.header -> footer.X; footer.X -> leftSidebar.footer ->
|
|
104
|
+
rightSidebar.footer -> header.X; leftSidebar.header -> header.start ->
|
|
105
|
+
rightSidebar.header -> footer.start; leftSidebar.footer -> footer.start ->
|
|
106
|
+
header.start -> rightSidebar.footer; rightSidebar.header -> header.end ->
|
|
107
|
+
leftSidebar.header -> footer.end; rightSidebar.footer -> footer.end ->
|
|
108
|
+
header.end -> leftSidebar.footer. The legacy `tenantFooter` prop keeps its own
|
|
109
|
+
`footerInHeader` fallback.
|
|
110
|
+
|
|
111
|
+
### Edge toggles and hotkeys are opt-in (#3661)
|
|
112
|
+
|
|
113
|
+
`AdminShell`/`AppShell` `edgeToggles?: boolean | Partial<Record<PanelEdge,
|
|
114
|
+
boolean>>` defaults to `false`: no edge toggle buttons, no hotkey hints, and
|
|
115
|
+
WASD/`?` are inert. Regions are laid out inline: the left sidebar is docked
|
|
116
|
+
open off phones (`ShellState.setInlineEdges`/`isInline`; viewport defaults and
|
|
117
|
+
`overlayMedia` do not apply), and the header/footer are plain bands without a
|
|
118
|
+
drop-down drawer (so `appPanel`/`systemPanel` are not reachable). Visibility
|
|
119
|
+
comes from `ShellLayout.panels.visible` and edit mode. The right edge is the
|
|
120
|
+
dock: dock toggles and focus tools still open it, it just loses its button.
|
|
121
|
+
`hotkeys` (default: follows the toggles) forces shortcuts on (`true`, panels
|
|
122
|
+
behave as drop-downs without buttons) or off. Phones keep the Menu opener and
|
|
123
|
+
the left drawer's close toggle. `showTenantToggle` is a deprecated alias for
|
|
124
|
+
`edgeToggles.left`. Migration: pass `edgeToggles` (true) to keep the previous
|
|
125
|
+
behaviour.
|
|
126
|
+
|
|
127
|
+
### Moving items between slots
|
|
128
|
+
|
|
129
|
+
Movable items have stable ids: dock toggles `dock:<tool>`, each host `slots`
|
|
130
|
+
snippet `slot:<slot>`, and host `slotItems` (`AppShell`, `{ id, label, slot,
|
|
131
|
+
render }[]`, exported type `ShellSlotItem`; keep ids stable, they are stored in
|
|
132
|
+
layouts). `AppShell` also supplies the built-in item `item:brand` (the shell
|
|
133
|
+
`logoSrc`/`logoAlt`, title and subtitle, linked to `homeHref` when set, default slot `header.start`, movable, same fallback chain
|
|
134
|
+
when the header is hidden); it sets `AdminShell` `brandInSlot` so the top band
|
|
135
|
+
draws no brand of its own (standalone `AdminShell` still does). The menu
|
|
136
|
+
opener and account content are not items yet (#3656 step 3).
|
|
137
|
+
|
|
138
|
+
`ShellLayout.placements?: Record<itemId, ShellSlot>` (additive, still version
|
|
139
|
+
1) overrides default slots. Pure helpers in `layout.ts` (also `./workspace/layout`):
|
|
140
|
+
`placeShellItem(layout, id, slot, defaultSlot?)` (passing the default drops a
|
|
141
|
+
no-op override; re-placing puts the item last), `resetShellItemPlacement`,
|
|
142
|
+
`resolveShellPlacements(items, layout)` (default order first, then placement
|
|
143
|
+
order; unknown ids and slots ignored) and `resolveShellVisiblePlacements(items,
|
|
144
|
+
layout, visible)` (placement first, then the hidden-region fallback above).
|
|
145
|
+
`useShellLayout()` adds `placeItem(id, slot)`, `resetItem(id)`, and readers
|
|
146
|
+
`placementItems`, `placements` (per slot) and `isRegionVisible(region)`.
|
|
147
|
+
|
|
148
|
+
### Editing the layout in place
|
|
149
|
+
|
|
150
|
+
`AppShell` `layoutEditing?: boolean | { slot?; floating? }` opts in (off: no toggle,
|
|
151
|
+
`setEditing(true)` refused, existing apps unchanged). It adds the built-in item
|
|
152
|
+
`item:layout-edit` (default slot `header.end`, normal hidden-region fallback):
|
|
153
|
+
a pencil `ShellIconButton` named "Edit layout" with `aria-pressed`; the same
|
|
154
|
+
button turns edit mode off (it stays a pencil, highlighted while on). Escape
|
|
155
|
+
also exits when no section toolbar is open (an open toolbar, or a keyboard move,
|
|
156
|
+
consumes Escape first).
|
|
157
|
+
`{ floating: true }` instead renders the same button fixed in the top-right
|
|
158
|
+
corner (round, elevated, safe-area aware, z-index 45): not a slot item, not
|
|
159
|
+
movable, never displaced by hidden regions. The header reserves end padding for
|
|
160
|
+
it, or, when the header is hidden, the right sidebar reserves top padding, or main
|
|
161
|
+
does when no right sidebar is shown
|
|
162
|
+
(`--smrt-shell-floating-reserve-inline|block|main`, set by `AppShell`).
|
|
163
|
+
A polite live region announces the mode. `useShellLayout()` has
|
|
164
|
+
`editable`, `editing` and `setEditing(boolean)` for hosts and assistants.
|
|
165
|
+
|
|
166
|
+
While `editing`:
|
|
167
|
+
|
|
168
|
+
- `AdminShell` `layoutEdit` (`ShellLayoutEditSurface`, set by `AppShell`) renders
|
|
169
|
+
every slot of a visible region as a dashed drop zone (entering edit mode
|
|
170
|
+
expands a collapsed left/right sidebar so its header/footer zones exist, and
|
|
171
|
+
leaving restores it; a railless `rail: false` edge is never revealed: it
|
|
172
|
+
stays as the user left it, and while editing a closed railless right edge
|
|
173
|
+
with focus/dock tools shows a slim "Open <tool>" indicator tab
|
|
174
|
+
(`data-edit-indicator`, z 21, no layout shift) that opens it and closes it
|
|
175
|
+
again on exit) (`data-smrt-edit-zone`)
|
|
176
|
+
labelled "Header · Left", empty ones included, highlighted
|
|
177
|
+
(`data-drop-target`) while a drag targets it. Movable items render exactly as
|
|
178
|
+
on the site (inside an `inert` wrapper) with a grip; the toggle itself is
|
|
179
|
+
fixed. One headless `createSortable` engine (confined to the shell root,
|
|
180
|
+
`allowSameContainerReorder: false`) drives pointer, native-drag and keyboard
|
|
181
|
+
moves (Space, Up/Down across zones in visual order, Enter drops, Escape
|
|
182
|
+
cancels) with the same announcements as `Sortable`
|
|
183
|
+
(`sortable/announce.ts`), committing `placeItem(id, slot)`. Items whose region
|
|
184
|
+
is hidden show in the zone they fall back to.
|
|
185
|
+
- Nothing in the header band renders outside the drop zones except each
|
|
186
|
+
region's edit control: the brand is an item in `header.start`, and the Menu
|
|
187
|
+
opener is hidden off phones. Every region, a collapsed sidebar rail included, gets an icon-only eye-off
|
|
188
|
+
"Hide <region>" button (`ShellLayoutEditSurface.regionControl`, end of the
|
|
189
|
+
header/footer band, top of a sidebar) that writes
|
|
190
|
+
`setPanel(edge, { visible: false })`; the strip's "Show" restores it. The
|
|
191
|
+
last visible region's button is disabled with an explanatory tooltip. Items
|
|
192
|
+
of a hidden region (the edit toggle included) follow the fallback chain.
|
|
193
|
+
Hiding the right sidebar (the dock) makes `useShellDock().available` false:
|
|
194
|
+
dock toggles render unregistered and `open` is refused until it is shown.
|
|
195
|
+
- Hidden, available regions render as thin dashed strips ("Right sidebar ·
|
|
196
|
+
hidden") with an eye "Show <region>" button (`setPanel(edge, { visible })`).
|
|
197
|
+
- `ShellNavEditor` replaces `TenantNav`: the real rows plus grips on every
|
|
198
|
+
heading and item (existing reorder/move-across-sections), icon-only
|
|
199
|
+
`ShellIconButton`s (eye `aria-pressed` = shown in navigation, heading
|
|
200
|
+
`aria-pressed` = title shown, host actions) on each section and an eye per
|
|
201
|
+
item, and a "New section" button at the end.
|
|
202
|
+
- Clicking a section heading opens its floating toolbar (rename input focused,
|
|
203
|
+
title, hide, delete for custom sections with a confirm when non-empty, host
|
|
204
|
+
actions). With `(hover: hover) and (pointer: fine)` hovering also opens it
|
|
205
|
+
(closes on leave unless a click pinned it); touch or no hover is click/tap
|
|
206
|
+
only. One toolbar at a time; Escape closes and returns focus to the heading;
|
|
207
|
+
a pinned toolbar closes on outside pointer or focus leaving.
|
|
208
|
+
|
|
209
|
+
Host extension point: `AppShell` `sectionActions?: Snippet<[ShellSectionActionsContext]>`
|
|
210
|
+
(`{ sectionId, label, custom, editing }`) renders icon buttons in both the
|
|
211
|
+
section overlay and its toolbar (e.g. the planner's Options gear and Help);
|
|
212
|
+
use `ShellIconButton` (from `./workspace`) for matching looks. It renders only
|
|
213
|
+
while editing.
|
|
214
|
+
|
|
215
|
+
`ShellLayoutEditor` no longer has a Placement section (superseded by dragging in
|
|
216
|
+
place); it keeps panels, the navigation sort (icon toggles `aria-pressed` for
|
|
217
|
+
"Show <name> in navigation" / "Show title of <name>"), the preview and Reset.
|
|
218
|
+
The layout helpers and `placeItem`/`resetItem` stay.
|
|
219
|
+
|
|
86
220
|
### Activity ticker
|
|
87
221
|
|
|
88
222
|
`ActivityTicker` accepts app-owned `activities: ReadonlyArray<ShellActivity>` plus
|
|
@@ -219,11 +353,75 @@ control panel), wired by `app/AppShell.svelte`.
|
|
|
219
353
|
`moveItem(id, sectionId, toIndex?)`, `hide(id)`, `show(id)`, `setPanel(edge,
|
|
220
354
|
{ visible?, initial? })`, `reset()`, each returning whether anything changed,
|
|
221
355
|
plus readers (`layout`, `sections`, `panels`, `applied`, `customized`,
|
|
222
|
-
`isHidden
|
|
356
|
+
`isHidden`; item placement is in "Moving items between slots", edit mode in
|
|
357
|
+
"Editing the layout in place"). An assistant calls the same methods the editor does. The
|
|
223
358
|
context is separate from `useAdminShell()` because `AppShell`, not
|
|
224
359
|
`AdminShell`, owns the navigation.
|
|
360
|
+
- **Sections belong to the app.** Hosts (and recipes, via the host) suggest
|
|
361
|
+
sections as `ShellNavGroup`s; the user overrides them in the same additive
|
|
362
|
+
version-1 layout: `sections[id] = { label?, showTitle? }` (rename; hide the
|
|
363
|
+
title) and `customSections: { id: 'custom:...', label }[]` (user-created).
|
|
364
|
+
Custom sections join `sectionOrder`, receive items through `moved`, show in
|
|
365
|
+
the editor when empty but not in the nav, and get a unique `custom:` id.
|
|
366
|
+
`showTitle: false` (also settable by a host on `ShellNavGroup.showTitle`)
|
|
367
|
+
renders the items flat in a `role="group"` named by the heading, no
|
|
368
|
+
`<details>`/`<summary>`. `applyShellLayout` keeps the section's original id
|
|
369
|
+
on renamed output groups. Helpers: `renameShellSection`,
|
|
370
|
+
`setShellSectionTitleVisible`, `createShellSection`, `deleteShellSection`
|
|
371
|
+
(custom only; items return to their default sections). Old stored layouts
|
|
372
|
+
need no migration; new host sections and items land in their suggested slot.
|
|
373
|
+
Controller: `renameSection`, `setSectionTitleVisible`, `createSection(label)`
|
|
374
|
+
(returns the id), `deleteSection`.
|
|
375
|
+
- **Item labels.** The same layout renames single navigation entries:
|
|
376
|
+
`items[itemId] = { label? }` (additive; trimmed, blank removed; ids as above,
|
|
377
|
+
top-level items of `nav` and groups). `resolveShellNavModel` items carry
|
|
378
|
+
`label` / `defaultLabel`; `applyShellLayout` emits the renamed item with
|
|
379
|
+
`label` = the user's and `defaultLabel` = the host's (so nav, breadcrumbs and
|
|
380
|
+
titles that read `nav` follow the rename). Helper `renameShellItem(nav, groups,
|
|
381
|
+
layout, itemId, label | null)`; controller `renameItem(itemId, label | null)`
|
|
382
|
+
(null or blank resets). Edit mode: each `ShellNavEditor` row has an icon-only
|
|
383
|
+
"Rename <label>" button opening an inline field (Enter saves, Escape cancels,
|
|
384
|
+
blur saves) and, once renamed, "Reset <label> to <original>"; the original shows
|
|
385
|
+
as the row tooltip. Presets ("cookbooks") ship it in the stored layout.
|
|
386
|
+
- **Sections-only navigation (`navMode: 'sections'`).** `AppShell` (and
|
|
387
|
+
`TenantNav` / `ShellNavEditor` directly) take `navMode?: 'items' | 'sections'`
|
|
388
|
+
(default `'items'`, unchanged). In `'sections'` the left sidebar shows one
|
|
389
|
+
link per section (icon + label), no entries; a collapsed rail (`tenantRail`)
|
|
390
|
+
shows the icons with tooltips. The link goes to `ShellNavGroup.href`, else
|
|
391
|
+
`AppShell` `sectionHref(sectionId)` (user-created sections), else the first
|
|
392
|
+
entry; it is `aria-current="page"` on that page and `"true"` on any of the
|
|
393
|
+
section's entry pages. `AppShell` also takes `iconComponent` for host icon
|
|
394
|
+
names. `ShellNavGroup.icon` / `.href` are additive; the user override is
|
|
395
|
+
`sections[id].icon` (trimmed; blank or the host's icon removes it), helper
|
|
396
|
+
`setShellSectionIcon(nav, groups, layout, id, icon | null)`, controller
|
|
397
|
+
`setSectionIcon(id, icon | null)`; `resolveShellNavModel` sections carry
|
|
398
|
+
`icon` / `defaultIcon` and `applyShellLayout` emits the effective `icon`.
|
|
399
|
+
Icons are shell icon names (`SHELL_SECTION_ICONS` is the picker set, drawn
|
|
400
|
+
from Material icons like the rest of `SHELL_ICON_PATHS`; `SHELL_DEFAULT_SECTION_ICON`
|
|
401
|
+
is `folder`) or host names rendered by `iconComponent` (`ShellSectionIcon`
|
|
402
|
+
tries the built-in set first). Edit mode in this mode: sections keep grip,
|
|
403
|
+
rename, hide, delete; the title toggle is replaced by an "Icon of <label>"
|
|
404
|
+
popover grid ("Use <icon> icon", `aria-pressed` on the current one; Escape
|
|
405
|
+
closes the grid before the toolbar). Entries are not in the sidebar.
|
|
406
|
+
- **`ShellSectionMenu`** (`sectionId`, `controller?`, `meta(entry)`,
|
|
407
|
+
`actions(entry)`, `iconComponent`, `aria-label`, `layout`): the section's page body.
|
|
408
|
+
`layout="cards"` renders an auto-fill grid (min 16rem) of cards: 32px icon in a
|
|
409
|
+
tinted circle, title, `ShellNavItem.description` (2 lines), then `meta` and
|
|
410
|
+
`actions` at the bottom; one stretched link, actions stay separate controls;
|
|
411
|
+
edit mode keeps grip/rename/hide in the grid. Unknown icon names draw the
|
|
412
|
+
default glyph (dev warning), never the name. `layout.items[id].description` (host/preset-set, not editable in the UI)
|
|
413
|
+
overrides an item's `description`. Default `list`: A
|
|
414
|
+
`<ul>` of rows (icon, label link, host `meta`, host `actions`, chevron; the
|
|
415
|
+
row is one stretched link, actions sit above it) in applied order with
|
|
416
|
+
renames; hidden entries are omitted. While editing, the same rows become the
|
|
417
|
+
nav editor's chrome (single-container `Sortable` grip with keyboard moves,
|
|
418
|
+
inline rename/reset, show/hide toggle) driving `moveItem`/`renameItem`/
|
|
419
|
+
`hide`/`show`; rows are not links then. `ShellSectionMenuEntry` is the snippet
|
|
420
|
+
argument (`id, href, label, defaultLabel, icon, hidden, item`).
|
|
225
421
|
- **`ShellLayoutEditor`**: `controller` (default: context), `preview` (default
|
|
226
|
-
true), `iconComponent`.
|
|
422
|
+
true), `iconComponent`. Each section has an inline name input, icon toggles
|
|
423
|
+
for visibility and title, and (custom only) a trash button, which confirms
|
|
424
|
+
when non-empty; a New section button creates one. Mount it on a settings page or in a dock tool.
|
|
227
425
|
|
|
228
426
|
### Sortable and the Board engine
|
|
229
427
|
|
|
@@ -255,9 +453,8 @@ lives beside, not inside, `./workspace` so the AdminShell barrel stays free of
|
|
|
255
453
|
(`{#snippet dock(registry)}`), the instance mounted routes register on
|
|
256
454
|
when `webmcp` UI is on; pass it to `<AssistantDock {registry} />`. `runtimeDiagnostics` (default false) mounts the
|
|
257
455
|
read-only `smrt.runtime.diagnostics.read` WebMCP tool. `dockToggles`
|
|
258
|
-
(`{ tool, label, icon? }[]`) renders icon buttons
|
|
259
|
-
|
|
260
|
-
each toggling the `ShellDockTool` with that id: `aria-pressed` and
|
|
456
|
+
(`{ tool, label, icon?, slot? }[]`) renders icon buttons in the shell slot
|
|
457
|
+
named by `slot` (default `header.end`; see "Regions and slots"), each toggling the `ShellDockTool` with that id: `aria-pressed` and
|
|
261
458
|
`aria-expanded` follow the dock, `aria-controls` is
|
|
262
459
|
`smrt-admin-shell-right-panel`, the label is the tooltip, and `assistant`
|
|
263
460
|
defaults to a chat-bubble icon (`icon: 'chat'`; other text is a glyph). A
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictation-source.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/adapters/stt/dictation-source.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dictation-source.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/adapters/stt/dictation-source.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,aAA0C,GAClD,MAAM,OAAO,CAAC,UAAU,CAAC,CAmB3B"}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* adapter lazily, once, the first time someone starts dictating: nothing
|
|
8
8
|
* loads and no microphone prompt appears until then. Defaults to the
|
|
9
9
|
* browser's own speech recognition (`browser-speech`), which needs no
|
|
10
|
-
* download; an
|
|
10
|
+
* download; an on-device model is never downloaded by dictation (see
|
|
11
|
+
* `LocalSpeechSTTAdapter.prepare`). An unsupported browser rejects with
|
|
11
12
|
* `CapabilityNotAvailableError`, which `Dictation` reports in plain words.
|
|
12
13
|
*
|
|
13
14
|
* @example
|
|
@@ -26,7 +27,12 @@ export function createSttDictationSource(options = { type: 'browser-speech' }) {
|
|
|
26
27
|
return () => {
|
|
27
28
|
adapter ??= (async () => {
|
|
28
29
|
const created = await getSTT(options);
|
|
29
|
-
|
|
30
|
+
// An adapter that needs a download is never loaded here: dictation must
|
|
31
|
+
// not start one. It checks its own model when started, and the host
|
|
32
|
+
// loads it explicitly (after asking).
|
|
33
|
+
if (!created.getCapabilities().requiresDownload) {
|
|
34
|
+
await created.ensureInitialized();
|
|
35
|
+
}
|
|
30
36
|
return created;
|
|
31
37
|
})().catch((error) => {
|
|
32
38
|
// Let a later tap try again (for example after a permission change).
|
|
@@ -20,8 +20,11 @@ import type { GetSTTOptions, STTAdapter } from './types.js';
|
|
|
20
20
|
* // Whisper.cpp (recommended for accuracy)
|
|
21
21
|
* const stt = await getSTT({ type: 'whisper-cpp', model: 'tiny.en' });
|
|
22
22
|
*
|
|
23
|
-
* // Whisper
|
|
24
|
-
* const stt = await getSTT({ type: 'whisper-
|
|
23
|
+
* // Local Whisper (transformers.js; WebGPU or WASM, one-time ~45 MB download)
|
|
24
|
+
* const stt = await getSTT({ type: 'whisper-local' });
|
|
25
|
+
*
|
|
26
|
+
* // Moonshine (fastest for live dictation, one-time ~32 MB download)
|
|
27
|
+
* const stt = await getSTT({ type: 'moonshine' });
|
|
25
28
|
* ```
|
|
26
29
|
*/
|
|
27
30
|
export declare function getSTT(options?: GetSTTOptions): Promise<STTAdapter>;
|
|
@@ -45,5 +48,5 @@ export declare function getSTTAuto(options?: Partial<Omit<GetSTTOptions, 'type'>
|
|
|
45
48
|
/**
|
|
46
49
|
* Check if a specific STT backend is available
|
|
47
50
|
*/
|
|
48
|
-
export declare function isSTTAvailable(type: 'browser-speech' | 'whisper-wasm'): boolean;
|
|
51
|
+
export declare function isSTTAvailable(type: 'browser-speech' | 'whisper-wasm' | 'whisper-local' | 'moonshine'): boolean;
|
|
49
52
|
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/adapters/stt/factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAEV,aAAa,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/adapters/stt/factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAEV,aAAa,EAEb,UAAU,EAEX,MAAM,YAAY,CAAC;AAkCpB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,CAuB7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,UAAU,CAC9B,OAAO,GAAE,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAM,GACjD,OAAO,CAAC,UAAU,CAAC,CAmBrB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,gBAAgB,GAAG,cAAc,GAAG,eAAe,GAAG,WAAW,GACtE,OAAO,CAgBT"}
|
|
@@ -12,10 +12,13 @@ function isBrowserSpeechOptions(options) {
|
|
|
12
12
|
return !options.type || options.type === 'browser-speech';
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Type guard for
|
|
15
|
+
* Type guard for on-device speech options (transformers.js): Whisper
|
|
16
|
+
* (`whisper-wasm` is the older name for `whisper-local`) and Moonshine.
|
|
16
17
|
*/
|
|
17
|
-
function
|
|
18
|
-
return options.type === 'whisper-
|
|
18
|
+
function isLocalSpeechOptions(options) {
|
|
19
|
+
return (options.type === 'whisper-local' ||
|
|
20
|
+
options.type === 'whisper-wasm' ||
|
|
21
|
+
options.type === 'moonshine');
|
|
19
22
|
}
|
|
20
23
|
/**
|
|
21
24
|
* Type guard for Whisper.cpp options (@remotion/whisper-web)
|
|
@@ -39,8 +42,11 @@ function isWhisperCppOptions(options) {
|
|
|
39
42
|
* // Whisper.cpp (recommended for accuracy)
|
|
40
43
|
* const stt = await getSTT({ type: 'whisper-cpp', model: 'tiny.en' });
|
|
41
44
|
*
|
|
42
|
-
* // Whisper
|
|
43
|
-
* const stt = await getSTT({ type: 'whisper-
|
|
45
|
+
* // Local Whisper (transformers.js; WebGPU or WASM, one-time ~45 MB download)
|
|
46
|
+
* const stt = await getSTT({ type: 'whisper-local' });
|
|
47
|
+
*
|
|
48
|
+
* // Moonshine (fastest for live dictation, one-time ~32 MB download)
|
|
49
|
+
* const stt = await getSTT({ type: 'moonshine' });
|
|
44
50
|
* ```
|
|
45
51
|
*/
|
|
46
52
|
export async function getSTT(options = {}) {
|
|
@@ -52,14 +58,16 @@ export async function getSTT(options = {}) {
|
|
|
52
58
|
const { WhisperCppSTTAdapter } = await import('./whisper-cpp.js');
|
|
53
59
|
return new WhisperCppSTTAdapter(options);
|
|
54
60
|
}
|
|
55
|
-
if (
|
|
56
|
-
const {
|
|
57
|
-
return new
|
|
61
|
+
if (isLocalSpeechOptions(options)) {
|
|
62
|
+
const { LocalSpeechSTTAdapter } = await import('./local-speech.js');
|
|
63
|
+
return new LocalSpeechSTTAdapter(options);
|
|
58
64
|
}
|
|
59
65
|
throw new UnsupportedAdapterError(String(options.type), [
|
|
60
66
|
'browser-speech',
|
|
61
67
|
'whisper-cpp',
|
|
68
|
+
'whisper-local',
|
|
62
69
|
'whisper-wasm',
|
|
70
|
+
'moonshine',
|
|
63
71
|
]);
|
|
64
72
|
}
|
|
65
73
|
/**
|
|
@@ -103,7 +111,9 @@ export function isSTTAvailable(type) {
|
|
|
103
111
|
if (type === 'browser-speech') {
|
|
104
112
|
return caps.stt.browserSpeechAPI;
|
|
105
113
|
}
|
|
106
|
-
if (type === 'whisper-wasm'
|
|
114
|
+
if (type === 'whisper-wasm' ||
|
|
115
|
+
type === 'whisper-local' ||
|
|
116
|
+
type === 'moonshine') {
|
|
107
117
|
return caps.stt.whisperWasm;
|
|
108
118
|
}
|
|
109
119
|
return false;
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
export { type BrowserSpeechError, BrowserSpeechSTTAdapter, } from './browser-speech.js';
|
|
5
5
|
export { createSttDictationSource } from './dictation-source.js';
|
|
6
6
|
export * from './factory.js';
|
|
7
|
+
export { LocalSpeechSTTAdapter, WhisperLocalSTTAdapter, WhisperWasmSTTAdapter, } from './local-speech.js';
|
|
8
|
+
export { createLocalSpeechModel, createWhisperLocalModel, isEnglishOnlyLocalSpeechModel, LOCAL_SPEECH_MODELS, type LocalSpeechDevice, type LocalSpeechLoadOptions, LocalSpeechModel, type LocalSpeechModelOptions, type LocalSpeechModelPreset, type LocalSpeechModelState, resolveLocalSpeechModelId, WHISPER_LOCAL_DEFAULT_MODEL, WHISPER_LOCAL_DEFAULT_SIZE_BYTES, type WhisperLocalDevice, type WhisperLocalLoadOptions, WhisperLocalModel, type WhisperLocalModelOptions, type WhisperLocalModelState, } from './local-speech-model.js';
|
|
9
|
+
export { configureTransformersEnv } from './transformers-env.js';
|
|
7
10
|
export * from './types.js';
|
|
8
11
|
export { WhisperCppSTTAdapter } from './whisper-cpp.js';
|
|
9
|
-
export { WhisperWasmSTTAdapter } from './whisper-wasm.js';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/adapters/stt/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,KAAK,kBAAkB,EACvB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,cAAc,cAAc,CAAC;AAC7B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/adapters/stt/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,KAAK,kBAAkB,EACvB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,6BAA6B,EAC7B,mBAAmB,EACnB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,yBAAyB,EACzB,2BAA2B,EAC3B,gCAAgC,EAChC,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,GAC5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
export { BrowserSpeechSTTAdapter, } from './browser-speech.js';
|
|
5
5
|
export { createSttDictationSource } from './dictation-source.js';
|
|
6
6
|
export * from './factory.js';
|
|
7
|
+
export { LocalSpeechSTTAdapter, WhisperLocalSTTAdapter, WhisperWasmSTTAdapter, } from './local-speech.js';
|
|
8
|
+
export { createLocalSpeechModel, createWhisperLocalModel, isEnglishOnlyLocalSpeechModel, LOCAL_SPEECH_MODELS, LocalSpeechModel, resolveLocalSpeechModelId, WHISPER_LOCAL_DEFAULT_MODEL, WHISPER_LOCAL_DEFAULT_SIZE_BYTES, WhisperLocalModel, } from './local-speech-model.js';
|
|
9
|
+
export { configureTransformersEnv } from './transformers-env.js';
|
|
7
10
|
export * from './types.js';
|
|
8
11
|
export { WhisperCppSTTAdapter } from './whisper-cpp.js';
|
|
9
|
-
export { WhisperWasmSTTAdapter } from './whisper-wasm.js';
|