refactor: drop Qwen3 CoreML ASR, add local-engine cloud polish toggle
Rolls back the v0.2.0 Qwen3 CoreML on-device ASR stack and replaces the
'local engine' UX with iOS 26 SpeechAnalyzer + DictationTranscriber only.
The 'Cloud polish after ASR' toggle (ProviderConfig.localModeCloudPolishEnabled)
lets users opt into a post-ASR DeepSeek round-trip from the local engine.
Defaults to off so the local engine stays genuinely local. New PolishError.missingAPIError
surfaces an inline 'fill in your key' warning when the toggle is on but the
Keychain is empty. DeepSeek preset default model bumped to deepseek-v4-flash.
Deleted:
- OSGKeyboard/ThirdParty/Qwen3Speech/ (74 files, ~16k LoC)
- OSGKeyboard/Services/ModelManager.swift (492)
- OSGKeyboard/Services/OnDeviceModelWarmup.swift (197)
- OSGKeyboard/Services/Qwen3ASRService.swift (257)
- OSGKeyboard/Services/ModelDownloadSourcePicker.swift (126)
- OSGKeyboard/Views/OnDeviceModelsView.swift (184)
- OSGKeyboard/Views/DownloadConfirmSheet.swift (96)
- OSGKeyboardShared/Models/OnDeviceModel.swift (140)
- OSGKeyboardShared/Services/OnDeviceModelStatus.swift (104)
- Qwen3ASRServiceProvider registration in OSGKeyboardApp
- Qwen3Speech package declaration in project.yml
- 5 .qwen3ASR enum / branch reference sites in HomeView, OnboardingView,
LocalEngineSettingsRows, FlowSessionManager, ASRService, EngineServiceLabel
- Two pre-existing Swift 6 strict-concurrency errors in
LiveDictationController + FlowSessionManager (the weak [weak self] in
detached-task MainActor.run blocks) that were blocking clean builds
Added:
- LocalModelsGroup: 'Built-in iOS SpeechAnalyzer' badge + 'Cloud polish
after ASR' Switch toggle
- PolishingService: honour localModeCloudPolishEnabled; new .missingAPIKey
error case with localised warning
- AppGroupStore.localModeCloudPolishEnabled (mirrored into App Group
so the keyboard extension honours the toggle during live dictation)
- SettingsView: show provider/api sections when local-mode cloud polish
is on so the user can paste a DeepSeek key
- FlowSessionManager: route through PolishingService for local + polish-on
flow; translate missingAPIKey into a polished warning
- KeyboardViewController: handle PolishingService.PolishError.missingAPIKey
in the keyboard-side live polish path
- CHANGELOG v0.2.1: documents the rollback + new toggle
- README.md / README.zh.md: engine matrix section, data flow note
Verified: xcodebuild -scheme OSGKeyboard -destination 'generic/platform=iOS Simulator'
build succeeds under SWIFT_STRICT_CONCURRENCY=complete.
This commit is contained in:
+6
-35
@@ -23,22 +23,12 @@ options:
|
||||
generateEmptyDirectories: true
|
||||
groupSortPosition: top
|
||||
|
||||
# Local package: `Qwen3Speech`. Vendored fork of
|
||||
# `soniqo/speech-swift`'s Qwen3-ASR + Qwen3-Chat modules (plus the
|
||||
# AudioCommon / MLXCommon / SpeechVAD slices they depend on).
|
||||
# Upstream's `Package.swift` references a `CSpeechCore` binary
|
||||
# target whose URL doesn't match its declared filename (the file
|
||||
# is `SpeechCore.xcframework.zip`, the target is `CSpeechCore`),
|
||||
# which breaks SwiftPM resolve on a clean checkout. Vendoring
|
||||
# lets us ship the four targets we actually link without waiting
|
||||
# for the upstream fix; the `audio` / `audio-server` CLIs and the
|
||||
# `AudioServer` HTTP backend that needed `CSpeechCore` aren't part
|
||||
# of OSGKeyboard's build graph. Sources carry their original
|
||||
# Apache-2.0 copyright headers; the `Package.swift` here adds
|
||||
# only what we need.
|
||||
packages:
|
||||
Qwen3Speech:
|
||||
path: OSGKeyboard/ThirdParty/Qwen3Speech
|
||||
# v0.2.0: dropped the local `Qwen3Speech` SPM fork. The "local" engine
|
||||
# now uses iOS 26 `SpeechAnalyzer` + `DictationTranscriber` exclusively,
|
||||
# which keeps the dependency surface at zero SPM packages / Pods /
|
||||
# Carthage (matches the long-standing "zero dependencies" promise in the
|
||||
# README). Optional post-ASR cloud polish routes through DeepSeek (or
|
||||
# any OpenAI-compatible endpoint) using the existing `LLMClient`.
|
||||
|
||||
settings:
|
||||
base:
|
||||
@@ -77,18 +67,6 @@ targets:
|
||||
# Legacy PNG app icons must not coexist with AppIcon.icon — actool
|
||||
# crashes when both are passed. iOS 26 uses Icon Composer only.
|
||||
- "Assets.xcassets/AppIcon.appiconset"
|
||||
# `ThirdParty/Qwen3Speech` is a local SPM package pulled in
|
||||
# by `packages:` below — it builds as its own targets
|
||||
# (`Qwen3ASR`, …) and we link the products.
|
||||
# If we don't exclude the source folder, xcodegen walks
|
||||
# into the package's `Sources/*/` directories and pulls
|
||||
# the swift files straight into the host app target,
|
||||
# which collides on duplicate type names (e.g. two
|
||||
# `Configuration.swift` files in `Qwen3ASR` and
|
||||
# `SpeechVAD`) and on multiple `@main` / top-level
|
||||
# declarations. Keep the folder as a package; don't
|
||||
# flatten it into the app.
|
||||
- "ThirdParty/Qwen3Speech"
|
||||
entitlements:
|
||||
path: OSGKeyboard/OSGKeyboard.entitlements
|
||||
properties:
|
||||
@@ -156,13 +134,6 @@ targets:
|
||||
- target: OSGKeyboardExt
|
||||
# Keyboard Extension is a plugin of the main App; embed it.
|
||||
- sdk: Speech.framework
|
||||
# Local fork of soniqo/speech-swift. See the `packages:`
|
||||
# block at the top of this file for the why-fork rationale.
|
||||
# Only the two products we actually link are listed; AudioServer
|
||||
# / AudioCLI (which is what the upstream binary target was
|
||||
# gating) aren't in our build graph.
|
||||
- package: Qwen3Speech
|
||||
product: Qwen3ASR
|
||||
|
||||
# =========================================================
|
||||
# Keyboard Extension
|
||||
|
||||
Reference in New Issue
Block a user