Repository navigation
Conversation
|
The following comment was made by an LLM, it may be inaccurate: |
82b68bc to
43ffd69
Compare
Adds opt-in voice dictation backed by any OpenAI-compatible transcription endpoint (local parakeet/whisper servers included). - TUI: Ctrl+Y records and sends, Alt+Y records and inserts. A REC line with a live waveform sits above the composer, with stop/send, pause/insert and cancel actions, and voice settings live in the /settings screen writing to the CLI config. - Web/desktop: a mic control in the composer with a live level meter. The composer send button stops the recording, transcribes, appends the text after whatever is already in the prompt and sends it. - Server: POST /api/voice/transcribe forwards audio to the configured endpoint, keeping the browser same-origin (no CORS issues). - Recordings are decoded and uploaded as 16 kHz mono WAV, since many local speech servers only accept WAV. - Voice ships unconfigured and reports a clear error until a server URL is set. Adds mic/pause icons and strings for every locale.
43ffd69 to
2dc57d0
Compare
|
Thanks for working on this! Am eagerly awaiting for some type of web dictation |
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
Issue for this PR
Related: #18226 (original web voice request, auto-closed after inactivity) and #29663 (earlier attempt against
dev, still open).Type of change
What does this PR do?
Adds optional voice dictation to the TUI and to the web/desktop client. Audio is transcribed by any OpenAI-compatible endpoint, so local servers (parakeet, whisper.cpp, …) work as well.
TUI
Ctrl+Ystarts recording; pressing it again (or Enter) stops, transcribes and sends the prompt.Alt+Yrecords and inserts without sending.REC 0:02line with a live waveform and elapsed time is shown above the composer, with stop/send, pause/insert and cancel actions, plus retry/discard when a transcription fails./settings(URL, API key, model) and are written to the CLI config.Web / desktop
Server
POST /api/voice/transcribeforwards the recording to the endpoint from the config. Transcribing server-side keeps the browser same-origin (no CORS setup needed) and works for desktop clients too.POST /api/voice/recordingemits avoice.recordingevent when a recording starts, so plugins and integrations can react — for example, pre-warming a local transcription server while the user is still speaking. The TUI and web clients send it fire-and-forget; with no subscribers the event is a no-op.Details
How did you verify your code works?
/settings) and the web client in Chrome (recording UI, stop-and-send merging with pre-existing prompt text, microphone denied, server unreachable, empty transcription).voice.recordingevent end-to-end: a test plugin subscribed to the event stream receives it as soon as a recording starts.bun run typecheckfor the touched packages (tui, app, client, protocol, server) andbun test packages/app/src/settings/general/controllers.test.ts.Screenshots / recordings
Web client in English, dark and light: recording (live level meter with the pause/cancel controls and the composer's stop-and-send button) and the transcription inserted into the composer. Plus the Voice settings section.
TUI while recording, with the level meter, elapsed time, and the stop/send, pause/insert and cancel controls above the composer:
About the diff size
Most of the diff is generated or mirrored, not hand-written:
packages/protocol/openapi.json,services/www/openapi.json,services/www/public/openapi.json), and regenerating it also syncs a pre-existing drift onv2: theLocationNotFoundError404 variants are already emitted by the generator source onv2but were missing from the committed spec (regenerating the plainv2protocol alone currently differs from the committed file by ~815 lines;bun run check:generatedfails onv2as-is and passes with this document). The voice routes themselves are only ~215 lines per copy.Checklist