Add experimental native speech-to-text support - #326
Merged
Conversation
Contributor
|
Chat app preview removed for |
There was a problem hiding this comment.
Pull request overview
Adds an experimental, typed speech-to-text surface to llamadart, centered on native llama.cpp whole-file transcription via a Qwen3-ASR profile, and wires it through docs, tests, tooling, and the Flutter chat example (including a verified-download preset).
Changes:
- Introduces
SpeechToTextEngine/ request + task/event model with capability discovery, cancellation, and transcript normalization. - Updates the chat app to expose a dedicated “Transcribe Audio” flow and adds a pinned Qwen3-ASR 0.6B preset with SHA-256 verification.
- Extends local E2E tooling/test matrix and updates documentation + changelogs to reflect the new experimental scope.
Reviewed changes
Copilot reviewed 42 out of 42 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| website/sidebars.ts | Adds the new Speech-to-Text guide to docs navigation. |
| website/docs/platforms/support-matrix.md | Documents the narrower STT support scope vs general runtime availability. |
| website/docs/guides/speech-to-text.md | New guide describing the experimental typed STT API and limitations. |
| website/docs/guides/multimodal.md | Clarifies generic LlamaAudioContent vs typed STT and links to the new guide. |
| website/docs/examples/chat-app.md | Documents the chat app’s separate transcription workflow and preset sourcing. |
| website/docs/changelog/recent-releases.md | Adds an Unreleased entry for the STT feature/preset. |
| tool/testing/test_matrix.dart | Adds a targeted local-only speech-to-text-smoke row. |
| tool/testing/run_local_e2e.dart | Adds --audio-path and scenario wiring/validation for the STT smoke. |
| test/unit/tooling/run_local_e2e_test.dart | Tests the new STT local E2E scenario dry-run and argument validation. |
| test/unit/core/speech/speech_to_text_web_test.dart | Ensures typed STT is explicitly unsupported on Web. |
| test/unit/core/speech/speech_to_text_test.dart | Unit tests for STT capability probing, normalization, cancellation, and errors. |
| test/unit/core/speech/speech_platform_web_test.dart | Verifies the web platform stub reports unsupported STT. |
| test/unit/core/speech/speech_platform_stub_test.dart | Verifies the native stub reports STT as supported. |
| test/unit/core/exceptions_test.dart | Adds coverage for new speech-related exception types. |
| test/e2e/backends/speech_to_text_e2e_test.dart | Adds a local-only real-model E2E STT validation harness. |
| README.md | Mentions the new experimental typed STT capability and links to docs. |
| lib/src/core/speech/speech_to_text.dart | Implements the typed STT engine/task/events/capabilities + transcript normalization. |
| lib/src/core/speech/speech_platform_web.dart | Web implementation for platform-level STT unavailability. |
| lib/src/core/speech/speech_platform_stub.dart | Non-web implementation enabling STT platform support. |
| lib/src/core/models/chat/content_part.dart | Updates LlamaAudioContent docs to clarify it’s generic multimodal input. |
| lib/src/core/exceptions.dart | Adds LlamaSpeechException and LlamaAudioFormatException. |
| lib/llamadart.dart | Exports the new speech-to-text API surface. |
| example/chat_app/test/unit_test.dart | Validates catalog ordering/source expectations and the pinned ASR preset metadata. |
| example/chat_app/test/settings_service_test.dart | Tests settings persistence/migration for the STT capability flag. |
| example/chat_app/test/model_service_test.dart | Adds tests for SHA-256 verified downloads and cleanup on checksum failure. |
| example/chat_app/test/model_download_controller_adapter_test.dart | Ensures download cache entries surface verified size/SHA metadata. |
| example/chat_app/test/model_card_test.dart | Widget coverage for STT capability display + projector requirement UX. |
| example/chat_app/test/manage_models_screen_download_test.dart | Tests STT search keywords and stale custom-entry replacement behavior. |
| example/chat_app/test/chat_input_test.dart | Covers the “Transcribe Audio” action availability and chat transcription lifecycle. |
| example/chat_app/README.md | Documents the chat app’s STT flow, limitations, and integrity verification. |
| example/chat_app/lib/widgets/model_card.dart | Requires projector availability for STT models and displays STT capability chip. |
| example/chat_app/lib/widgets/chat_input.dart | Adds the “Transcribe Audio” attachment action. |
| example/chat_app/lib/services/settings_service.dart | Persists model_supports_speech_to_text and migrates Qwen3-ASR selection. |
| example/chat_app/lib/services/model_service_io.dart | Adds SHA-256 verification, caching, and discard-on-mismatch behavior. |
| example/chat_app/lib/services/model_download_controller_adapter.dart | Populates cache entries with bound remote asset size/SHA; clears STT when omitting projector. |
| example/chat_app/lib/screens/manage_models_screen.dart | Adds STT search terms and persists STT capability in custom models. |
| example/chat_app/lib/providers/chat_provider.dart | Implements dedicated STT picking/transcription flow and hardens lifecycle cancellation/unload. |
| example/chat_app/lib/models/downloadable_model.dart | Adds STT capability fields and a pinned Qwen3-ASR preset with integrity metadata. |
| example/chat_app/lib/models/chat_settings.dart | Adds persisted STT capability flag in settings. |
| example/chat_app/lib/models/chat_message.dart | Adds isTranscription derived flag to suppress regeneration for STT outputs. |
| doc/testing_matrix.md | Documents the new STT smoke row and its invocation. |
| CHANGELOG.md | Adds an Unreleased entry summarizing the experimental STT feature and preset. |
Suppressed comments (2)
lib/src/core/speech/speech_to_text.dart:560
- Same issue here: the exception
detailsis set torequest.audio.format, which is not very actionable in error output. Including the rejected file extension would make diagnostics clearer.
!const <String>{'wav', 'mp3', 'flac'}.contains(extension)) {
throw LlamaAudioFormatException(
'Encoded audio files must use WAV, MP3, or FLAC.',
request.audio.format,
);
lib/src/core/speech/speech_to_text.dart:575
LlamaAudioFormatExceptionusesrequest.audio.formatasdetails, which will usually render asInstance of ...in logs. Passing the rejected encoding string provides more actionable diagnostics for byte-backed inputs.
throw LlamaAudioFormatException(
'Encoded audio bytes must use WAV, MP3, or FLAC.',
request.audio.format,
);
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This was referenced Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SpeechToTextEnginefor whole-file Qwen3-ASR transcription over native llama.cppThe root problem is that generic
LlamaAudioContentgeneration had no stable transcription contract and could not distinguish audio-understanding chat from an ASR workflow.Related to #325. This PR intentionally does not close the issue.
Production-readiness scope
Completeness checklist
PR type guidance
Test Plan
dart format --output=none --set-exit-if-changed lib test tool example/chat_app/lib example/chat_app/testdart analyze lib test toolflutter analyzeinexample/chat_appdart test -p vm -j 1 --exclude-tags local-only— 1,347 passeddart test -p chrome --exclude-tags local-only— 742 passedflutter testinexample/chat_app— 215 passed./tool/docs/validate_links.sh./tool/docs/build_site.shMatrix Evidence
speech-to-text-smokeexamples-testsReview Notes
6d837317b411071732e383acdb5b6f12876d9585; the separate Copilot reviewer check also passed.