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
Transcribe an audio file to text over your own whisper.cpp server, no model turn per file.
Media
1
script
false
typescript
audio
transcription
transcribe
name
description
required
file_path
Path to the audio file to transcribe. Auto-filled from the file browser.
true
type
extensions
file
mp3
wav
m4a
Transcribe Audio File
Sends the audio file to the transcribe plugin's own route — POST /api/transcribe/transcribe — and
files the result next to the original.
A script task, deliberately: the plugin already does its own language detection and transcription
server-side, so there is nothing here worth a model turn for. Running one per audio file would be a
model call spent re-deriving what the plugin already returns.
What it does
Read the audio file at file_path and the caller's spoken-language preferences
(GET /api/user/settings).
POST the file to /api/transcribe/transcribe. The plugin detects the language and transcribes
faithfully in it — see plugins/transcribe/skills/transcribe/SKILL.md for the contract.
Create a sibling directory named <date>_<slug>, where <date> is today in YYYYMMDD and <slug>
is derived from the original file's own name (not a generated title — a script task gets no model
turn to ask for one).
Move the original audio file into that directory and save the transcription beside it as a
Markdown file with the same base name.
Before it runs
The plugin has to be configured — PUT /api/transcribe/config with a reachable whisper.cpp URL. If it
is not, this fails with that told plainly rather than a generic error.
What it deliberately does not do
The worked example this was adapted from (an agentic task) ran its own detect-language pass before
transcribing, and generated a title from the transcription's contents. Both are dropped here: the
detect-then-transcribe step is already what the plugin's route does internally, so repeating it would be
redundant work against the same server. And a generated title needs a model turn, which is exactly what
this task exists to avoid spending per file.