Whisper Local for DeepSeek Harness
Local, offline speech recognition for the DeepSeek Harness Web GUI, powered by
whisper.cpp. It plugs into the
Harness voice-input pipeline as a host-local speech provider: audio is
recorded by the browser, transcribed on the Host machine, and never sent over
the network.
- No OpenAI account, no API key.
- 99 Whisper languages plus automatic language detection.
- Model selector built into the Harness UI.
- Managed runtime and model downloads with size + SHA-256 verification.
- Agent tool
whisper_model so the assistant can inspect and change the model.
This is a community bundle, not an official DeepSeek plugin.
Table of contents
Features
- Fully local dictation |
whisper-cli.exe runs on the CPU; the model and
audio stay on the machine.
- Automatic language detection by default |
language: auto lets Whisper
identify each recording's language; any of the 99 Whisper languages can still
be forced from the voice settings.
- Model selection in the UI | pick tiny, base, small, medium or
large-v3-turbo from the plugin page; the change is persisted and applied
immediately.
- Managed setup | the Windows x64 whisper.cpp runtime and GGML model are
downloaded on demand, verified (size + SHA-256), cached, and reused offline.
- No microphone data retention | each recording is written to a temporary
WAV, transcribed, then deleted.
- Agent integration | the assistant can list models, download one in the
background, or switch the active model through
whisper_model.
How it works
Browser (Harness composer)
└─ microphone button records 16 kHz mono PCM WAV
└─ speech Remote sends the recording to the Host
└─ whisper-local SpeechProvider
├─ writes a temporary WAV
├─ spawns whisper-cli.exe with the selected GGML model
├─ reads the text output
└─ deletes the temporary files and returns the transcript
The provider registers through ctx.speechToText.register() and advertises
itself as location: 'host-local', so the voice UI shows preparation state and
lets the user download the model when needed.
Requirements
| Requirement | Details |
|---|
| DeepSeek Harness | Desktop/Web build with the experimental Voice Input bundle enabled |
| OS | Windows 10/11 x64 (the pinned runtime is a Windows CPU build) |
| Runtime | tar.exe (built into Windows 10/11) for extracting the runtime archive |
| Disk | ~90 MB for the extracted runtime + 31–547 MB per model (see table) |
| CPU | Any x64 CPU; more cores and threads improve speed. GPU is not used |
| Microphone | OS + browser microphone permission |
No Node.js, Python, compiler, or CUDA installation is required at runtime.
Installation
- Make sure the official Voice Input bundle is enabled:
Plugins → Voice Input.
- Install this bundle from a local directory:
Plugins → Add plugin → Install a third-party plugin, then enter the
absolute path to this folder (
.../dsh-whisper-local).
Alternatively, use the plugin manager's local-directory install target.
- The bundle's patch selects
whisper-local with language: auto for the
voice module and registers the whisper_model tool.
- If the Host module was added while Harness is running and the provider does
not appear, restart the Harness application once. Browser-only UI changes
are hot-reloaded.
The first dictation may show the voice setup prompt when the selected model is
missing; Go to setup opens the Voice Input details where preparation runs.
Selecting a model on the plugin page starts its preparation automatically.
Once prepared, recognition works fully offline.
Usage
Dictation
- Click the microphone button in the composer, between the model selector
and Send.
- Allow microphone access the first time.
- Speak, then press Stop.
- The transcript is inserted into the draft; review and send it normally.
Choosing a model
Open Plugins → Whisper local. The bundle page offers:
- a model dropdown with sizes and speed/accuracy hints;
- the currently active model;
- a Save model button.
The selection is written through the Harness Settings service into the profile
configuration, so it survives restarts. If the chosen model is not downloaded
yet, preparation starts automatically; progress is shown in the Voice Input
bundle details (Download and prepare).
Language selection
Whisper local advertises 99 languages plus auto. Change the language in
Plugins → Voice Input → bundle details → Language. The official selector
displays translated labels for auto, en, zh, ja, ko; other languages
appear as ISO codes such as fr, de, es, ja.
The default is auto (automatic detection), not a fixed language. French is
not forced: a recording is detected on its own unless a specific language is
selected. Automatic detection is a good default for mixed-language use; forcing
the exact language improves reliability on short or noisy recordings.
Models
All models are multilingual Whisper GGML builds, hosted by
ggerganov/whisper.cpp.
| Key | File | Size (binary) | Notes |
|---|
tiny-q5_1 | ggml-tiny-q5_1.bin | ~31 MB | Fastest, lowest accuracy |
base-q5_1 | ggml-base-q5_1.bin | ~57 MB | Fast, basic accuracy |
small-q5_1 | ggml-small-q5_1.bin | ~181 MB | Default; good balance |
medium-q5_0 | ggml-medium-q5_0.bin | ~514 MB | More accurate, slower |
large-v3-turbo-q5_0 | ggml-large-v3-turbo-q5_0.bin | ~547 MB | Best multilingual accuracy |
Measured on an AMD Ryzen 9 9950X3D with 8 threads, for roughly 10 seconds of
speech:
| Model | French | Japanese |
|---|
small-q5_1 | ~1.3 s | ~1.2 s |
large-v3-turbo-q5_0 | ~3.3 s | ~4.0 s |
The pinned whisper.cpp runtime is the official nightly
b5454 Windows x64 OpenBLAS build, verified by its release SHA-256.
Configuration
The bundle patch (cordis.patch.yml) supplies defaults:
- insert:
- id: whisper-local
name: '@local/dsh-whisper-local'
config:
dataRoot: !!js dshHomePath('speech-to-text', 'whisper-local')
model: small-q5_1
threads: 8
timeoutMs: 180000
- id: speech-to-text
config:
defaultProvider: whisper-local
language: auto
| Field | Default | Meaning |
|---|
dataRoot | %USERPROFILE%\.dsh\speech-to-text\whisper-local | Managed location for runtime, models and diagnostics |
model | small-q5_1 | One of the model keys above; also editable from the UI |
threads | 8 | CPU threads passed to whisper-cli |
timeoutMs | 180000 | Per-transcription deadline |
modelPath | unset | Use an existing GGML model file instead of a managed download |
whisperCli | unset | Use an existing whisper-cli.exe instead of the managed runtime |
User overrides are stored in the profile's patch layer and take precedence over
the bundle defaults. The model selected from the UI is written there as well.
Agent tool
The bundle registers the whisper_model tool:
| Action | Description |
|---|
list | Model catalogue, downloaded state, active model, preparation phase, active downloads |
download | Download a model in the background without changing the active model |
set | Select a model and persist it through Settings; downloads it unless prepare=false |
prepare | Prepare/download the currently selected model |
Example: switch to the large model after downloading it in the background.
{ "action": "download", "model": "large-v3-turbo-q5_0" }
{ "action": "set", "model": "large-v3-turbo-q5_0", "prepare": false }
Data and privacy
- No network calls during dictation. The only network traffic is the
one-time runtime/model download performed by the explicit preparation step.
- No API keys. The plugin never asks for or stores an OpenAI key.
- Temporary audio. Each recording becomes a temporary WAV under the OS temp
directory and is removed in a
finally block after transcription.
- Managed data lives in
dataRoot:
runtime/ | extracted whisper.cpp build and runtime.json marker;
model/ | downloaded GGML models;
cache/ | downloaded runtime archive;
status.json | diagnostic snapshot (provider, model, languages, selected
language, readiness). No audio or transcript content is stored there.
- Settings persistence uses the profile's
cordis.patch.yml; the model
choice contains no sensitive data.
Troubleshooting
The microphone says the provider is not ready.
Open Plugins → Voice Input → details and use Download and prepare. The
setup card downloads the runtime and model and shows progress.
The model selector shows "settings unavailable".
The Harness Settings service or configForms client service is not mounted in
this profile. Use the voice bundle's preparation page or edit model in the
profile patch.
No audio is recognized.
Check the OS microphone permission, that a model is prepared, and the selected
language. Try auto, or force the spoken language. For quiet/short recordings,
a larger model helps.
The plugin row is failed after an update.
The bundled provider.js is plain JavaScript and needs no build, but Host
modules are loaded once per process. Toggling the row or restarting Harness
reloads the module. Check the row's diagnostic in Plugins.
Diagnostics.
dataRoot/status.json reports the active model, advertised language count,
selected provider/language and readiness. The agent can also call
whisper_model with action: "list".
Development
No build step. The bundle is plain ESM/JavaScript.
| File | Role |
|---|
package.json | Bundle manifest (dsh.bundle.patch, dsh.client, exports) |
cordis.patch.yml | Cordis rows: the provider and the voice selection override |
index.js | Cordis entry; loads Schemastery from the dsh installation and declares the volatile model Config field |
provider.js | Speech provider: preparation, downloads, verification, whisper-cli execution, whisper_model tool |
client.js | Browser page: model selector through ctx.configForms |
locale/*.json | Plugin-manager display metadata (en, fr, zh) |
tests/*.mjs | Provider and client tests |
tests/fixtures/*.wav | Small multilingual TTS fixtures for the integration tests |
Tests
The provider tests run real transcription with the prepared model in the
default dataRoot, so prepare the runtime/model first (or point
WHISPER_LOCAL_DATA_ROOT at a prepared directory):
node tests/local-provider.test.mjs
node tests/client.test.mjs
The provider suite covers: provider registration and language list,
idempotent preparation, real French transcription, unprepared-state errors,
explicit English/German/Spanish/Japanese transcription, automatic detection,
model listing through the agent tool, persistence through Settings and invalid
model rejection.
Limitations
- Windows x64 only for the managed runtime. The provider logic is portable,
but the pinned download is a Windows build; other platforms need a different
whisperCli/runtime and extraction path.
- CPU inference only in this configuration; no GPU acceleration.
- Complete recordings only | no streaming captions, wake word or automatic
send; those are capabilities of the voice subsystem, not this provider.
- Accuracy varies by model and language. Low-resource languages may need a
larger model.
- The official Voice Input selector shows ISO codes for languages without a
translated label.
large-v3-turbo needs roughly 1–2 GB of RAM during inference and is slower
than small; choose based on your hardware.
Acknowledgements
The plugin code itself is provided as part of this repository; add or adapt the
license notice to match the repository's licensing before publishing.
"# dsh-whisper-local"