pastilhas 964f1a53b7 the language-detection pass is optional now
every transcription on this machine failed with "Language detection failed
(400)" before it started. the server was fine — it had answered /inference
correctly minutes earlier — and the platform was fine. the plugin's FIRST
call sends detect_language=true, which is a whisper.cpp parameter, and
whisperx answers 400 to it.

so a pass that exists to HELP became the only thing that could fail, on a
backend that does its own detection anyway. whisperx logs "No language
specified, language will be detected for each audio file" and gets it
right per file.

a backend refusing that request is telling us it detects for itself. skip
the pass, send no `language`, and read back whatever the transcription
reports. the two-pass path is untouched for whisper.cpp, which needs it,
and the spoken-language tie-break still applies wherever detection runs.

no prompt priming when the language is unknown either — TRANSCRIPT_PROMPTS
is keyed by language, and priming with the wrong one is worse than not
priming.
2026-08-25 05:37:50 +00:00

Transcribe

Officer's speech-to-text, talking to a self-hosted whisper.cpp server.

Transcribe does not run Whisper and ships no model. You point it at a whisper.cpp /inference server you already run and it forwards to it, tuned for one person talking into a phone: detect the spoken language, then transcribe faithfully in it — never translated, never guessed at in English when the audio is not.

What you get

  • POST /api/transcribe/transcribe — send an audio file, get back its text and the language Whisper detected. Two-pass under the hood (detect, then transcribe in that language) so a low-confidence guess never quietly defaults to English.
  • Conversations come back as conversations. Nobody declares what a recording is — a probe on the diarization worker runs alongside every transcription and finds out. Solo dictation returns as paragraphs, exactly as before; a recording with several voices returns speaker-labeled (Speaker 1: …) with conversation: true and a speaker count. The worker is optional: without it, or if it fails mid-request, everything still transcribes — just never labeled. See ~/dockers/torch-worker for the worker itself.
  • Fair queueing for a multi-user server. Transcription and diarization each run one job at a time behind their own queue, in arrival order — and on different hardware, so the conversation probe costs a solo memo nothing.
  • A file-browser task. Right-click an .mp3, .wav or .m4a and transcribe it without a model turn — the task is a plain script that calls this plugin's own route and files the result next to the original.
  • A skill, so an agent asked to transcribe something knows the route, the shape, and what to say when nothing is configured, without being told.

What you need

A whisper.cpp server you already run, reachable from this machine, answering POST /inference — the same container the platform used to talk to directly. Nothing else. No system packages, no host binaries; the sidecar reaches it with fetch.

Setup

PUT /api/transcribe/config
{ "url": "http://192.168.1.50:64201" }

Validated against the server before it is stored — a wrong URL is a 400 with the reason, not a saved value that fails on the first real transcription.

What this plugin deliberately does not have

  • No dashboard route, no dock tile. There is nothing to look at — this is reached through the file browser's task menu and by an agent that has read the skill, not through a screen. Shipping no web/ is a supported shape, not an oversight.
  • No streaming. One file in, one answer back. If you want a live microphone, that is a different feature built on top of this one, not something this plugin does today.
  • No translation. It transcribes in whatever language was spoken. Whisper's own translate mode is English-only, so honouring "translate into <language>" for anything else would mean silently handing back a rough English rendering of, say, Portuguese audio — worse than refusing.
S
Description
Speech to text for Officer — audio files transcribed through a Whisper server
Readme
132 KiB
Languages
TypeScript 100%