feat(voice): integrate hero_voice_admin for in-app transcription #84
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Replace hero_slides internal voice recording (
voice.transcribeAsyncRPC) with thehero_voice_adminservice, which provides a proper transcription pipeline with local STT (sherpa-onnx Parakeet) and Groq cloud fallback.What was attempted
Commit
f38547awired all per-field mic buttons to POST audio to/hero_voice/ui/transcribevia hero_router. Reverted in642b4afbecausehero_voice_admindoes not exist yet — only ahero_voiceCLI binary is installed, so the endpoint returns 404.Blocked on
hero_voice_adminservice needs to be built and deployed (serves/hero_voice/ui/transcribe,/hero_voice/ui/rpc, and the<hero-voice-bar>widget bundle)hero_voicedlocal STT service (sherpa-onnx Parakeet on127.0.0.1:8094) needs to be running, orGROQ_API_KEYset in hero_proc secrets as cloud fallbackIntegration plan (ready to apply once hero_voice_admin exists)
/hero_voice/ui/voice-widget/inbase.htmlpollAiJob('voice.transcribeAsync', ...)calls indashboard.jsandslide_edit.jswithfetch('/hero_voice/ui/transcribe', { method: 'POST', body: FormData })returning{ text }<hero-voice-bar>to the navbar for global focus-aware transcriptionI would suggest that we use
hero-voice-bareverywhere that we need voice functionality. In terms of the slides app, this could go once in the main navbar header. But most of the text input happens in pop-up modals, so I would just suggest to add the bar into each of those modals as well. Then the existing voice functionality in slides can just be stripped out.Implementation Spec — Issue #84
Objective
Replace the internal voice recording pipeline in hero_slides (which called
voice.transcribeAsyncviapollAiJoband drove its own MediaRecorder lifecycle) with thehero-voice-barweb component fromhero_voice_admin. One instance lives in the navbar (tracks the last-focused field globally), and additional instances are placed inside each modal/overlay that contains text inputs. All internal voice code is deleted.Requirements
components.js,floating.js,boost.js,bar.js) and CSS (voice-widget.css) from/hero_voice/ui/voice-widget/in both page templates (base.htmlandslide_edit.html).<hero-voice-bar>in the navbar ofbase.htmlso it is always visible on the main dashboard page.<hero-voice-bar>inside each modal and overlay panel inindex.htmlthat contains text inputs where voice input makes sense (5 locations).<hero-voice-bar>inslide_edit.htmlfor both the main editor textarea and the instruct panel input.dashboard.jsandslide_edit.js(MediaRecorder-based functions, module-level variables, event-listener wires).index.htmlandslide_edit.html.index.html..slide-edit-voice-statusCSS rule fromslide_edit.css.Files to Modify
crates/hero_slides_admin/templates/base.html— Add widget CSS/JS, add<hero-voice-bar>in navbarcrates/hero_slides_admin/templates/index.html— Add<hero-voice-bar>in 5 locations, remove old mic buttons/status spans, remove Transcription Settings panelcrates/hero_slides_admin/static/js/dashboard.js— Delete voice functions and module-level variablescrates/hero_slides_admin/templates/slide_edit.html— Add widget CSS/JS, add<hero-voice-bar>in 2 locations, remove old mic buttons/status spanscrates/hero_slides_admin/static/js/slide_edit.js— DeletecreateRecorderfactory, recorder instances, event-listener wirescrates/hero_slides_admin/static/css/slide_edit.css— Delete.slide-edit-voice-statusruleImplementation Plan
Step 1 — Load widget assets in
base.htmlFiles:
crates/hero_slides_admin/templates/base.htmlDependencies: none
<head>, add after the existingconnection-status.csslink:<link href="/hero_voice/ui/voice-widget/voice-widget.css" rel="stylesheet" /></body>, add the four scripts in order beforedashboard.js:components.js,floating.js,boost.js,bar.js<hero-voice-bar></hero-voice-bar>in the navbarms-autodiv, immediately after<hero-connection-status>Step 2 — Load widget assets in
slide_edit.htmlFiles:
crates/hero_slides_admin/templates/slide_edit.htmlDependencies: none
<head>slide_edit.jsat the bottom of the fileCan run in parallel with Step 1.
Step 3 — Add
<hero-voice-bar>and strip old voice UI fromslide_edit.htmlFiles:
crates/hero_slides_admin/templates/slide_edit.htmlDependencies: Step 2
<hero-voice-bar>(one inslide-edit-instruct-controls, one inslide-edit-actions)<div id="voice-status">and<div id="instruct-voice-status">elementsStep 4 — Remove voice JS from
slide_edit.jsFiles:
crates/hero_slides_admin/static/js/slide_edit.js,crates/hero_slides_admin/static/css/slide_edit.cssDependencies: none
createRecorderfactory functionmainRecorderandinstructRecorderconstant declarations.slide-edit-voice-statusCSS rule fromslide_edit.cssCan run in parallel with Steps 1–3.
Step 5 — Add
<hero-voice-bar>and strip old voice UI fromindex.htmlFiles:
crates/hero_slides_admin/templates/index.htmlDependencies: none
5 locations to update (replace old mic buttons + status spans with
<hero-voice-bar>):btn-record-start/btn-record-stop+#voice-status)btn-instruct-record/btn-instruct-record-stop+#instruct-voice-status)btn-theme-record-start/btn-theme-record-stop+#theme-voice-status)btn-theme-instruct-record/btn-theme-instruct-record-stop+#theme-instruct-voice-status)btn-create-slide-record/btn-create-slide-record-stop+#create-slide-voice-status)Also remove the Transcription Settings admin panel section (
<div class="admin-section" id="section-transcription-settings">).Can run in parallel with Steps 1–4.
Step 6 — Remove voice JS from
dashboard.jsFiles:
crates/hero_slides_admin/static/js/dashboard.jsDependencies: none
Delete:
startCreateSlideRecordingandstopCreateSlideRecordingfunctionsstartThemeInstructRecordingandstopThemeInstructRecordingfunctionsstartRecording,stopRecording,sendAudioToServerfunctionssaveTranscriptionSettings,onTranscriptionBackendChange,loadTranscriptionSettingsfunctionscreateSlideMediaRecorder,mediaRecorder,audioChunks,isRecordingCan run in parallel with Steps 1–5.
Acceptance Criteria
<hero-voice-bar>appears in the navbar on the main dashboard page<hero-voice-bar>is visible inside the Create Slide modal, markdown editor topbar, markdown instruct panel, theme editor topbar, and theme instruct panel<hero-voice-bar>is visible in the slide_edit page for both the main editor and the instruct panelpollAiJob('voice.transcribeAsync', ...)remain in the JS codebasedashboard.jsorslide_edit.jsonclickreferences: all removed functions are fully gone from both HTML and JS files.slide-edit-voice-statusCSS rule is deletedNotes
/hero_voice/ui/transcribe) internally; no{{ base_path }}prefix needed for the scriptsrcattributes.voice.transcribeAsynchandlers,VoiceTranscribejob type,voice.rslib, Rhaivoice_module.rs, openrpc.json voice entries) is out of scope — only the UI/JS layer is touched.hero_voice_admindoes not need to be running for the UI changes to be committed; the widget will gracefully handle unavailability.