Commit Graph
6 Commits
Author SHA1 Message Date
pastilhas 8c0366fdbc the task takes a destination
output_dir, optional. absent, the text lands beside the recording as it
always has — that is what a person right-clicking a memo wants and it is
not changing. given, the transcript goes there instead, and the directory
is created if it does not exist.

for callers that are not a person clicking a file. a commander keeps its
results in its own directory, and the alternative was making every
commander move the file afterwards: a step in the loop forever, plus a
window where the file sits in the folder being watched.

marked `hidden` so the file browser neither shows it nor counts it as
something to ask about — without that, declaring it turned a direct
right-click run back into a modal with a field nobody clicking a file has
an answer for.
2026-08-25 04:56:43 +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
pastilhasandClaude Opus 5 887eed226b the transcription goes beside the audio, and nothing else moves
it created a dated directory, moved the recording into it and wrote the
markdown alongside. nobody asked for an archive. the thing you want from a
transcription is the text next to the recording, which is exactly what the
file viewer's transcribe button did — POST with saveNextTo, sibling .md,
done.

overwrites a previous transcription of the same file on purpose: it is
derived, running it again means you wanted it again, and a -2 beside it is
only a second file to choose between.

inline: true, so the file browser runs it and waits rather than making a
background job out of a call that takes seconds.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
2026-08-24 04:47:05 +00:00
pastilhasandClaude Opus 5 3d2e4afd4e declare the whisper server as a setting
This plugin ships no web/, so there was nowhere to set its server URL — the only
way in was an HTTP call somebody had to already know about. That is not a
setting, it is a secret handshake, and it is the state this shipped in.

Declared rather than rendered: the platform draws the form on the plugin detail
page and PUTs to this plugin's own /config. It stores nothing, so the URL stays
where this plugin already kept it and the validation against the server still
happens here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
2026-08-24 04:00:03 +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