Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9c150a6
feat(platform): voice brain-dump onboarding step
Abhi1992002 Aug 2, 2026
0759e0f
refactor(frontend): drop brain-dump dev scaffolding before release
Abhi1992002 Aug 2, 2026
e424d5b
fix(frontend): commit PrivacyNote, drop unused imports, regenerate op…
Abhi1992002 Aug 2, 2026
57c84c4
fix(frontend): report the real recording duration when stopping
Abhi1992002 Aug 2, 2026
537179a
fix(backend): stop re-claiming a brain dump that is already processing
Abhi1992002 Aug 2, 2026
709eefe
fix: address review findings across the brain-dump pipeline
Abhi1992002 Aug 2, 2026
38d66ae
test(backend): keep the brain-dump route tests off the network
Abhi1992002 Aug 2, 2026
8181fde
fix(backend): fall back to the browser duration when ffmpeg cannot probe
Abhi1992002 Aug 2, 2026
0c196b1
fix(frontend): stop the greeting-retire call retrying, handle copy fa…
Abhi1992002 Aug 2, 2026
bfcaff3
fix(backend): enforce the recording size cap after the write, regen s…
Abhi1992002 Aug 2, 2026
e734001
fix(backend): let the caller say which take to discard
Abhi1992002 Aug 2, 2026
3a384fc
test(frontend): pin that captions reconnect when the stream arrives late
Abhi1992002 Aug 2, 2026
07ac241
fix(backend): claim a take atomically before finalizing it
Abhi1992002 Aug 2, 2026
6d3ee55
fix: never fall through a lost claim; nudge on real silence
Abhi1992002 Aug 2, 2026
04118db
fix(frontend): keep both onboarding flags defaulted off
Abhi1992002 Aug 2, 2026
5e61c44
fix(frontend): show the composer when the brain-dump flag is off
Abhi1992002 Aug 3, 2026
b3a84bb
test(frontend): cover the brain-dump onboarding surface
Abhi1992002 Aug 3, 2026
58d12ed
fix(frontend): rename a test binding that shadowed `module`
Abhi1992002 Aug 3, 2026
34b2633
test(backend): pin that a finalize with no parts writes no row
Abhi1992002 Aug 3, 2026
a4b89e7
feat(frontend): flag-gate the brain-dump experience end to end
Abhi1992002 Aug 3, 2026
19189a8
fix(backend): send split brain-dump segments with an ogg filename
Abhi1992002 Aug 3, 2026
1369722
fix(frontend): keep the onboarding flag defaults off
Abhi1992002 Aug 3, 2026
46ec5ca
fix(frontend): stop the greeting heading jumping in from the page centre
Abhi1992002 Aug 3, 2026
6741126
Merge branch 'dev' into abhi/onboarding-brain-dump
Abhi1992002 Aug 3, 2026
b776206
fix(backend): stop a superseded finalize reporting another take's status
Abhi1992002 Aug 3, 2026
de7f408
fix(backend): keep a finalize with no dump row from discarding the bu…
Abhi1992002 Aug 3, 2026
8311ae4
fix(frontend): gate brain-dump handoff on the flag and stop unbounded…
Abhi1992002 Aug 4, 2026
f789a0c
fix(backend): bound the split loop, scope post-claim writes to the take
Abhi1992002 Aug 4, 2026
cc59e9a
fix(frontend): guard double-start, gate skip during submit, fail uplo…
Abhi1992002 Aug 4, 2026
91a4489
ci(frontend): apply prettier to the new LiveCaptions test
Abhi1992002 Aug 4, 2026
c02657b
fix(backend): build the STT client per call, and sync the API schema
Abhi1992002 Aug 4, 2026
87e94df
fix(frontend): stop a discarded take's drain touching the new take's …
Abhi1992002 Aug 4, 2026
6f37686
fix(backend): clear take-owned columns on a new take, stop superseded…
Abhi1992002 Aug 4, 2026
47d3179
fix(backend): record brain dump storage failures
Abhi1992002 Aug 4, 2026
9acb1bf
fix(backend): protect active dumps from stale typed requests
Abhi1992002 Aug 4, 2026
cc56ef7
fix(backend): preserve voice mode during typed retries
Abhi1992002 Aug 4, 2026
cc6f3fa
Merge remote-tracking branch 'upstream/dev' into abhi/onboarding-brai…
Abhi1992002 Aug 5, 2026
8fd0454
fix(backend): make brain dump upserts retry-safe
Abhi1992002 Aug 5, 2026
a88ceb4
refactor(frontend): remove live transcription
Abhi1992002 Aug 5, 2026
e7ceded
fix(backend): fix onboarding brain dump persistence
Abhi1992002 Aug 5, 2026
532c77d
fix(backend): protect uploaded brain dumps
Abhi1992002 Aug 5, 2026
1be1dea
Merge branch 'dev' into abhi/onboarding-brain-dump
Abhi1992002 Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions autogpt_platform/backend/.env.default
Original file line number Diff line number Diff line change
Expand Up @@ -294,3 +294,30 @@ TALLY_API_KEY=

# Other Services
AUTOMOD_API_KEY=

## ===== ONBOARDING BRAIN DUMP ===== ##
# The voice brain-dump onboarding step is gated on the `onboarding-brain-dump`
# LaunchDarkly flag and is fail-closed: the endpoints 404 unless it is on.
#
# Left commented deliberately — .env.default ships to every install, and an
# active override here would force the feature on for everyone and bypass
# LaunchDarkly. Uncomment in your own .env to test locally, and set the
# matching NEXT_PUBLIC_FORCE_FLAG_ONBOARDING_BRAIN_DUMP in frontend/.env.
# FORCE_FLAG_ONBOARDING_BRAIN_DUMP=true

# Speech-to-text model for the brain dump. Requires a direct OpenAI key
# (OPENAI_INTERNAL_API_KEY, else OPENAI_API_KEY) — OpenRouter has no
# /audio/transcriptions endpoint. Falls back automatically on failure.
# BRAIN_DUMP_TRANSCRIPTION_MODEL=gpt-4o-transcribe
# BRAIN_DUMP_TRANSCRIPTION_FALLBACK_MODEL=whisper-1

# Greeting generation for the copilot home after onboarding. The prompt is
# managed in Langfuse under BRAIN_DUMP_GREETING_PROMPT_NAME when Langfuse
# credentials are configured; otherwise a built-in prompt is used.
# BRAIN_DUMP_GREETING_MODEL=anthropic/claude-sonnet-5
# BRAIN_DUMP_GREETING_PROMPT_NAME=Brain Dump Greeting

# Model that picks which integrations to suggest in the welcome dialog's
# "Connect your tools" panel. Recommendations are best-effort — a failure
# here never blocks onboarding.
# BRAIN_DUMP_RECOMMEND_MODEL=anthropic/claude-sonnet-5
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Brain-dump transcription eval

WER (word error rate) harness for the onboarding brain-dump transcription
pipeline (`transcription.py`). It runs the **real** pipeline — same models,
same retry/fallback, same ffmpeg splitting and stitching — against a corpus of
recordings with human-written reference transcripts, and reports how far the
machine transcript drifts from the truth.

**Release gate: aggregate (pooled) WER must stay under 5%.** The harness exits
`1` when it is at or above 5%, `0` otherwise, so it can be wired into a release
check as-is.

## Running it

```bash
# from autogpt_platform/backend
poetry run brain-dump-eval --dir /path/to/dumps

# override the primary model (fallback stays whisper-1)
poetry run brain-dump-eval --dir /path/to/dumps --model gpt-4o-mini-transcribe

# also dump machine-readable results
poetry run brain-dump-eval --dir /path/to/dumps --json /tmp/wer.json
```

Run `poetry install` once after pulling this in — `brain-dump-eval` is a new
console script and won't exist in an older virtualenv. Equivalent without it:

```bash
poetry run python -m backend.api.features.onboarding_dump.brain_dump_eval --dir /path/to/dumps
```

Requires a direct OpenAI key (`OPENAI_INTERNAL_API_KEY` or `OPENAI_API_KEY`) —
OpenRouter does not implement `/audio/transcriptions`. Recordings above the
single-request byte cap also need `ffmpeg` on `PATH`.

**This costs real money and real minutes.** A 25-file, 2–15 minute corpus is
roughly 3 hours of audio per run. Run it before a transcription change ships,
not on every commit.

## The corpus

Put the recordings and their reference transcripts in one flat directory,
matched **by basename**:

```
dumps/
dump01.webm dump01.txt
dump02.m4a dump02.txt
dump03-es.mp3 dump03-es.txt
```

- Audio extensions: `.webm` `.mp4` `.m4a` `.mp3` `.wav` `.ogg`
- Reference: same basename, `.txt`, UTF-8, plain text (no timestamps, no
speaker labels)
- Unmatched files are skipped and listed at the bottom of the report, so a
typo'd basename never silently shrinks the corpus.

### What to record — please help fill this out

We need **25+ real rambling dumps**. Not scripts read aloud: the pipeline's
failure mode is messy natural speech, so read-aloud audio will pass at ~1% WER
and tell us nothing. Target mix:

- **25+ recordings**, each **2–15 minutes** long
- **Mixed accents** — at minimum US, UK, Indian, and non-native-English
speakers
- **Background noise** — a few from a café, a street, a room with a fan, a
phone on speaker
- **At least 3–4 non-English dumps** (e.g. Spanish, French, Hindi). The
pipeline must transcribe in the language spoken, never translate — a
non-English dump that comes back in English is a bug even at low WER
- **At least 2 long ones (>20 MB)** so the chunked/stitched path is exercised
- Real rambling: false starts, "um", topic switches, self-corrections, long
pauses

### Writing the reference transcript

Type what was actually said, verbatim: keep filler words and false starts, drop
nothing. Don't clean up grammar. Punctuation, casing and hyphenation don't
matter — the harness lowercases, strips punctuation and collapses whitespace
before comparing — but *words* do.

## Reading the report

```
file WER sub ins del ref secs segments
dump01 3.20% 8 2 1 344 12.4 1
dump02 7.10% 15 4 3 312 41.9 3

Stitch boundaries (chunked files):
dump02 — 3 segments
seam 0/1: dedup dropped 7 word(s)
...so then I went back to the drawing
board and I thought maybe the whole thing
seam 1/2: dedup dropped 0 word(s)
...

pooled WER 4.30% (656 reference words)
mean WER 5.15%
median WER 5.15%
wall clock 54.3s

Release gate: aggregate WER must stay under 5% — PASS (exit 0)
```

- **pooled WER** — errors over all reference words in the corpus. This is the
gated number; long files count more, which is what we want.
- **mean / median WER** — per-file averages. A mean far above the pooled number
means a small file is failing badly; look at the per-file rows.
- **sub / ins / del** — substitutions dominate for accents and jargon,
insertions for hallucination (the failure mode that matters most: a
hallucinated sentence becomes a "fact" about the user), deletions for
dropped audio and bad seams.
- **segments** — `1` means single-request; more means the chunked path ran.
- **Stitch boundaries** — for chunked files only, the last ~10 words of each
segment and the first ~10 of the next, plus how many words the overlap-dedup
removed. `dropped 0` at a seam usually means the dedup failed to find the
overlap and the transcript now repeats a phrase; a large drop means it ate
real speech. Both show up as insertions/deletions in the WER but are only
diagnosable here.

A file whose transcription raised is shown as `ERROR` and forces a failing exit
regardless of WER.

## Notes / limits

- The harness has no duration metadata for the files, so it takes the
single-request vs chunked decision on the byte cap
(`SINGLE_REQUEST_MAX_BYTES`) alone — exactly what
`transcribe(audio, filename, duration_secs=None)` does. In production the
frontend supplies a duration, so a long-but-small recording can chunk there
and not here.
- WER is computed with an inline Levenshtein over normalised words
(`brain_dump_wer.py`); no `jiwer` dependency.
- The corpus is deliberately **not** committed — the recordings are personal
speech. Keep them in shared storage and point `--dir` at a local copy.
Loading
Loading