4 Commits
Author SHA1 Message Date
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
pastilhasandClaude Fable 5 dd3dbb611b conversations come back as conversations
A probe on the torch stage worker (~/dockers/torch-worker) runs beside every
transcription and decides what the recording is: solo dictation returns as
paragraphs exactly as before, several voices return speaker-labeled with
conversation: true. Nobody declares which — the caller cannot know.

Transcription and the worker each get a serial FIFO queue on their own
resource, so the probe costs a solo memo nothing and multi-user traffic
stays fair. The worker is optional and best-effort throughout: unreachable
or failing, everything still transcribes, just never labeled.

Speaker attribution is segment-granularity by maximal turn overlap —
whisper.cpp's own timestamps, no alignment stage. If boundaries prove
sloppy, wav2vec2 alignment returns as a worker endpoint.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 04:27:14 +00:00
pastilhas bd08f9a5fe no idle timeout on the sidecar's own server
this holds a connection open while whisper works, and nothing flows on it
meanwhile — exactly what an idle timeout kills. unset, Bun drops the
platform's connection at around 255s.

it was the last of three hops still doing it. the proxy's outbound fetch
and the platform's inbound timeout were both fixed earlier today and a
42-minute recording still died at 4m16s. whisperx went on and finished it;
the result was discarded.

with diarization on, align runs at roughly 1.5x the audio duration, so an
hour-long episode needs ninety minutes. no ceiling is both safe and high
enough, and 255 is Bun's maximum anyway — "raise it" was never available.
0 disables it.
2026-08-24 21:22:52 +00:00
pastilhas 3da6d11c00 extract speech-to-text into its own plugin
Moves platform STT out into a plugin that owns the whole whisper.cpp contract: sidecar,
config (a JSON file under DATA_PATH/transcribe/, validated against the server before
storing), a thin proxy router, a skill so an agent knows the contract without being told,
and a script-mode file-browser task (not agentic — no model turn per audio file).

sidecar/transcribe.ts and its test moved unchanged from src/servers/api/stt/ — every
constant in it has a reason attached and none of it was touched.

The platform-side removal (routes, dead useAudioRecording path, Settings screen, locale
keys) lands in a separate, uncommitted change in the platform repo for review.

Not yet reachable from the file browser: the platform does not load tasks from a plugin's
directory yet (skills/affordances/notifications do). Ships anyway per instructions.

Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
2026-08-24 03:28:04 +00:00