Skip to content

feat: add push-to-talk voice dictation with Parakeet - #240

Open
EduCosta85 wants to merge 2 commits into
HKUDS:mainfrom
EduCosta85:feat/composer-voice-dictation-parakeet
Open

EduCosta85 wants to merge 2 commits into
HKUDS:mainfrom
EduCosta85:feat/composer-voice-dictation-parakeet

Conversation

@EduCosta85

Copy link
Copy Markdown

Summary

This PR adds push-to-talk voice input directly to the composer. Spoken text is recorded locally, transcribed via an OpenAI-compatible speech-to-text server (such as NVIDIA Parakeet served by mlx-audio), and inserted directly into the prompt draft at the caret position.

What is included

  1. Protocol & App Server:
    • dictation/status method returning endpoint capability (available, model, maxAudioSeconds). Added to READ_METHODS for safe retries.
    • dictation/transcribe method receiving { audio, mimeType, language?, projectId? } and returning { text, model }. Kept out of READ_METHODS.
  2. Configuration (DictationConfig):
    • Declared under dictation in user configuration (~/.deepcode/deepcode_config.json).
    • Validates endpoint (must be absolute HTTP/HTTPS without userinfo, query, or fragment).
    • Project-level configurations cannot configure or hijack the dictation endpoint; repository overrides are dropped during layer sanitization.
  3. Core & Audio Pipeline:
    • Pure container sniffing for audio formats (webm, ogg, mp4, wav, mp3, flac, aac) matching declared MIME types.
    • Caps payloads at 512 KiB decoded / 768 KiB base64 to stay well within the JSON-RPC message envelope.
    • Synchronous SpeechToTextClient targeting POST <endpoint>/audio/transcriptions with multipart form data, no redirect following, and zero response-body leakage in error messages.
  4. Application & Policy:
    • DictationService coordinates egress verification (providers.egress), audio decoding, client dispatch, and error translation.
  5. Desktop & Web UI:
    • useDictation React hook managing recording state, platform-compatible MIME negotiation (MediaRecorder), timers, chunked base64 conversion, and cancellation.
    • Composer microphone button with recording animation, timer hint, discard button (X), and Escape shortcut to cancel.
    • Caret-aware insertion: dictated text is spliced into the existing textarea draft without losing cursor position.
  6. Documentation & Tests:
    • New guide docs/guide/dictation.md covering mlx-audio local Parakeet setup, config reference, and security boundaries.
    • Unit test suites covering audio decoding, client network behaviors, application service, dispatcher RPC, config layering, and frontend hook interactions.

Verification

  • pytest tests/test_dictation.py tests/test_dictation_service.py tests/test_config_layering.py tests/contract/test_protocol_schema.py: 105 passed.
  • ruff check and ruff format --check (v0.15.21): Clean.
  • python -m compileall -q app_server cli core tools workflows: Passed.
  • npm run lint: Clean.
  • npm run typecheck: Passed without errors.
  • npm test -- --run (including useDictation.test.ts): 40 test files passed, 274 tests passed.
  • npm run check:protocol, check:version, check:tauri: All passed.

Support push-to-talk voice dictation directly in the composer.
Speech clips recorded via MediaRecorder are validated, decoded, and
forwarded over JSON-RPC to a local speech-to-text server exposing
an OpenAI-compatible transcription endpoint (such as NVIDIA Parakeet
running on mlx-audio).

- protocol: define dictation/status and dictation/transcribe in JSON-RPC schema
- config: add user-owned DictationConfig with endpoint, model, timeout, and cap settings
- core: implement pure audio container sniffing and OpenAI-compatible client
- application: implement DictationService with model egress policy checks
- desktop: add useDictation hook and composer push-to-talk microphone button
- docs & tests: add complete unit test suites and setup documentation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant