Skip to content

Voice: add speech-recognition language selection (Wispr Flow) (QUALITY-1066) - #13720

Draft
warp-agent-staging[bot] wants to merge 3 commits into
masterfrom
factory/voice-language-selection
Draft

Voice: add speech-recognition language selection (Wispr Flow) (QUALITY-1066)#13720
warp-agent-staging[bot] wants to merge 3 commits into
masterfrom
factory/voice-language-selection

Conversation

@warp-agent-staging

@warp-agent-staging warp-agent-staging Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Client half of QUALITY-1066 (voice language selection). Adds a "Speech Recognition Language" dropdown to Settings → AI → Voice so a user can pin the language Wispr Flow transcribes in. The selection flows from the client → the warp-server transcribe API → the Wispr Flow request body. "Auto-detect" (the default) sends no language, preserving today's behavior.

This is the client half; the server half (which forwards the language to Wispr) lives in the matching PR below. Both must ship for the feature to work end to end.

Changes

  • app/src/settings/ai.rs: new VoiceInputLanguage enum setting — AutoDetect default, cloud-synced globally (SyncToCloud::Globally(RespectUserSyncSetting::Yes)), toml_path agents.voice.voice_input_language; plus code() (ISO 639-1) and display_name() helpers. Field added to AISettings.
  • app/src/settings_view/ai_page.rs: renders the "Speech Recognition Language" dropdown immediately below the "Key for Activating Voice Input" dropdown, inside the same is_voice_input_enabled gate; adds the SetVoiceInputLanguage action + handler, the AISettingsChangedEvent::VoiceInputLanguage subscription, and enable/disable wiring.
  • app/src/voice/transcriber.rs, app/src/server/voice_transcriber.rs: Transcriber::transcribe gains language: Option<String>, forwarded onto TranscribeRequest.
  • app/src/editor/view/voice.rs and app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs: read the setting and pass the language at both transcribe call sites.
  • app/src/settings/ai_tests.rs: unit tests for the enum default/code() and TranscribeRequest language serialization.

Language list (v1, curated): Auto-detect + en, es, fr, de, it, pt, nl, hi, ja, ko, zh, ar, ru, pl, sv, tr, uk, id, vi, th.

Verification

  • Unit tests: voice_input_language_default_is_auto_detect, voice_input_language_code_returns_iso_639_1_code, transcribe_request_omits_language_for_auto_detect, transcribe_request_includes_selected_language.
  • ./script/format --check passes; ./script/check_no_inline_test_modules passes.
  • cargo check --tests -p warp passes (the test crate, including ai_tests.rs, type-checks cleanly). Building/running the full warp lib test binary OOMs in this 15 GB sandbox (the single rustc --test process for the warp lib exceeds the memory limit); CI runs the full test suite.
  • cargo clippy -p warp --all-targets --tests -- -D warnings passes with both default features and --features voice_input.

Visual proof (user-facing change) — captured from a signed-in, AI-enabled build

The Warp GUI was built from this branch (cargo build --bin warp --features voice_input, the internal/dogfood channel) and launched signed in via WARP_API_KEY against staging. The "Speech Recognition Language" dropdown was exercised on screen:

  1. Voice section, Voice Input ON — both dropdowns visible:
    Voice section, Voice Input ON
  2. Dropdown default = "Auto-detect" (closed dropdown):
    Dropdown default Auto-detect
  3. Dropdown expanded — full 21-option list (Auto-detect; English; Spanish (Español); French (Français); German (Deutsch); Italian (Italiano); Portuguese (Português); Dutch (Nederlands); Hindi (हिन्दी); Japanese (日本語); Korean (한국어); Chinese (中文); Arabic (العربية); Russian (Русский); Polish (Polski); Swedish (Svenska); Turkish (Türkçe); Ukrainian (Українська); Indonesian (Bahasa Indonesia); Vietnamese (Tiếng Việt); Thai (ไทย)):
    Dropdown expanded
  4. A different language selected — the closed dropdown label updates (here to "Indonesian (Bahasa Indonesia)"):
    Selected language
  5. Voice Input toggled OFF — both the "Speech Recognition Language" and "Key for Activating Voice Input" dropdowns are hidden:
    Voice Input OFF

Screenshots are hosted on a throwaway draft release (voice-language-proof-QUALITY-1066, no tag created) purely to attach the images to this PR; it can be deleted after this PR merges.

Rework (review cycle 1)

  • Addressed the review nit: hoisted the use crate::ai::voice::transcribe::TranscribeRequest; import from inside the two new test functions to the top of app/src/settings/ai_tests.rs (the file's top-level-import convention). No behavior change (commit 786d5e1).
  • Addressed the blocking review concern (missing visual evidence): captured the signed-in visual proof above.

Matching PR

Server half: https://github.com/warpdotdev/warp-server/pull/12740

Originating thread: https://warpdotdev.slack.com/archives/C0BDQDW8V5E/p1784060704730339

Spec: agents/specs/QUALITY-1066: voice language selection.md (committed in this PR)

This PR was generated with Oz.

Add the approved-pending spec for the Voice language selection option
(Wispr Flow): a Speech Recognition Language dropdown in Settings -> AI ->
Voice, an enum-backed VoiceInputLanguage setting (Auto-detect default),
client->server language passthrough via the Transcriber trait, and server
forwarding of language into the Wispr Flow request body. Cross-repo change;
matching spec PR in warpdotdev/warp-server.

Co-Authored-By: Warp <agent@warp.dev>
@cla-bot cla-bot Bot added the cla-signed label Jul 14, 2026
Add a "Speech Recognition Language" dropdown to Settings -> AI -> Voice so
users can pin the language Wispr Flow transcribes in. Introduces a
VoiceInputLanguage enum setting (AutoDetect default, cloud-synced globally),
renders the dropdown below the toggle-key dropdown (gated on Voice Input being
enabled), and extends the Transcriber::transcribe trait to carry an optional
language forwarded via TranscribeRequest. AutoDetect sends no language,
preserving today's behavior.

Wired at both transcribe call sites (editor voice input and the CLI agent
footer). Adds unit tests for the enum default/code() and TranscribeRequest
language serialization.

Part of QUALITY-1066.

Co-Authored-By: Warp <agent@warp.dev>
@warp-agent-staging warp-agent-staging Bot changed the title Spec: Voice language selection (QUALITY-1066) Voice: add speech-recognition language selection (Wispr Flow) (QUALITY-1066) Jul 15, 2026

@warp-agent-staging warp-agent-staging Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

Client half of QUALITY-1066 (voice language selection). Adds a VoiceInputLanguage enum setting (AutoDetect default, cloud-synced globally), a "Speech Recognition Language" dropdown in Settings → AI → Voice (gated on Voice Input enabled), and extends Transcriber::transcribe with language: Option<String> wired at both call sites (editor/view/voice.rs and the CLI agent_input_footer). The code is a faithful, correct mirror of the existing VoiceInputToggleKey pattern.

What I verified (the code is sound)

  • VoiceInputLanguage mirrors VoiceInputToggleKey exactly: same derive list, same #[schemars(... rename_all = "snake_case")], same implement_setting_for_enum! shape (differing only in SyncToCloud::Globally vs Never, the toml path, and the description — all per spec). ISO 639-1 code() values are correct (en, es, … th).
  • The AISettingsChangedEvent::VoiceInputLanguage variant is macro-generated by define_settings_group! from the new voice_input_language field on AISettings (confirmed in crates/settings/src/macros.rs) — so no explicit enum edit was needed.
  • The dropdown creation, SetVoiceInputLanguage handler, render call, and event subscription all mirror the toggle-key equivalents, including the is_voice_input_enabled gate. Sensible additions: set_menu_max_height for the longer 22-item list, and correctly omitting the explicitly_interacted_with_voice one-time flag (per spec). LocalOnlyIconState::for_setting correctly shows no local-only icon for this globally-synced setting.
  • Both transcribe call sites read voice_input_language.code().map(...) and pass Option<String>; AutoDetectNonelanguage omitted end-to-end. Unit tests cover default/code()/TranscribeRequest serialization (omits for AutoDetect, includes "nl" for Dutch).

Concern

  • Missing visual evidence (blocking). This is a user-facing UI change (a new dropdown). The attached screenshot shows the Voice section with the Voice Input toggle disabled (AI requires a signed-in account) — it does not show the "Speech Recognition Language" dropdown rendered, the "Auto-detect" default, the option list, or the hide-when-Voice-Input-off behavior. Per this repo's review-pr-local guidance, author environment limitations (logged-out OSS sandbox) do not exempt user-facing changes from visual evidence. Please attach a screenshot or short recording captured in a signed-in, AI-enabled Warp environment showing: (1) the dropdown rendered below the key dropdown with "Auto-detect" selected by default; (2) a different language selected with the label updated; (3) the dropdown hidden when Voice Input is toggled off. The OSS sandbox can't sign in (this review sandbox has the same limitation), so capture it from a local desktop or a computer-use-enabled credentialed environment (see Warp's computer use docs). This corresponds to spec validation criteria #4 and #5, which are currently unmet.

Note

The matching server PR (#12740) has a separate review comment on the Wispr language field shape (the documented API expects a list ["en"], but the server sends a bare string). Resolving that is also required for the feature to work end-to-end.

Minor (non-blocking)

The new tests in ai_tests.rs embed use crate::ai::voice::transcribe::TranscribeRequest; inside two test functions; the file's convention is top-level imports (5 top-level use statements, 0 embedded elsewhere). Consider hoisting it to the top with the other imports.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes — the code is correct, but a user-facing dropdown change requires visual evidence of the rendered dropdown (Auto-detect default + option list + hide-when-off) captured in a signed-in, AI-enabled environment before merge.

@advait-m
advait-m self-requested a review July 15, 2026 00:49
The two new voice-language transcribe tests embedded a
`use crate::ai::voice::transcribe::TranscribeRequest;` inside the test
functions; the file's convention is top-level imports. Hoist it to the
top with the other `use crate::...` statements and drop the two embedded
copies. No behavior change.

Addresses review nit on #13720 (QUALITY-1066).

Co-Authored-By: Warp <agent@warp.dev>
@warp-agent-staging

Copy link
Copy Markdown
Contributor Author

Rework (review cycle 1) — changes requested addressed.

Visual proof (the blocking concern): Captured from a signed-in, AI-enabled build. The Warp GUI was built from this branch (cargo build --bin warp --features voice_input, internal/dogfood channel) and launched signed in via WARP_API_KEY against staging. The "Speech Recognition Language" dropdown was exercised on screen — default "Auto-detect", the full 21-language option list, selection updates the label, and it hides when Voice Input is toggled off:

Dropdown default Auto-detect
Dropdown expanded — 21-language list
Selected language updates the label
Voice Input OFF — dropdown hidden

Full set + the expanded list are in the PR description. (Images are hosted on a throwaway draft release voice-language-proof-QUALITY-1066 — no tag created — purely to attach them here; deletable after merge.)

Nit (non-blocking): Also hoisted the use crate::ai::voice::transcribe::TranscribeRequest; import from inside the two new test functions to the top of app/src/settings/ai_tests.rs (786d5e1).

Note on the matching server PR (#12740): the Wispr language field is now sent as a single-element list []string{request.Language} per Wispr Flow's documented API (confirmed against the API docs), so a selected language flows end-to-end correctly.

@warp-agent-staging warp-agent-staging Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review (rework cycle 1) — verdict: Approve

Blocker resolution verified

The blocking finding from the prior review (missing visual evidence for a user-facing change) is resolved. The PR body now embeds 5 screenshots captured from a signed-in dogfood build of this branch (--features voice_input, staging auth). This review downloaded and inspected the assets directly and validated them against the spec's acceptance criteria:

  • Invariants #1/#2: the "Speech Recognition Language" dropdown renders in Settings → AI → Voice immediately below "Key for Activating Voice Input", with Auto-detect selected by default. ✔
  • Full list: the expanded dropdown shows all 21 options (Auto-detect + 20 languages with native names). ✔
  • Invariant #3: selecting a language updates the closed dropdown's label (shown with "Indonesian (Bahasa Indonesia)"). ✔
  • Hide gate / criterion #5: with Voice Input toggled off, both dropdowns are hidden (not greyed out). ✔

The prior nit (test-only import hoisted to the top of ai_tests.rs) was addressed in commit 786d5e1 with no behavior change.

Rubric

Correctness, naming, comments, tests, and security all look good. The setting mirrors the existing VoiceInputToggleKey pattern; cloud sync choice (Globally(RespectUserSyncSetting::Yes)) matches the spec's rationale; the Transcriber trait change is wired at both transcribe call sites (editor + CLI agent footer) — a correct superset of the spec. The 4 unit tests cover default, code() mapping, and TranscribeRequest serialization for both Auto-detect and selected-language cases.

Notes for the human merger (not blocking)

  • CI coverage: the Rust CI jobs (Formatting + Clippy, tests, release compilation) are skipped on this draft PR — they run when the PR is marked ready / enters the merge queue. Locally the author validated ./script/format --check, cargo check --tests -p warp, and cargo clippy -p warp --all-targets --tests -- -D warnings (both feature sets); the full test binary OOMs in the 15 GB sandbox. Confirm the full suite is green once marked ready.
  • The throwaway draft release hosting the screenshots (voice-language-proof-QUALITY-1066) can be deleted after merge.

Verdict

Found: 0 critical, 0 important, 0 suggestions

Approve

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant