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
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# 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.
|
||||
- **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.
|
||||
Reference in New Issue
Block a user