feat(translation): add post-ASR translation mode for cloud engine

Adds an opt-in translation pipeline that reuses the existing
PolishingService + LLMClient + AppGroupStore chain. Translation is
implemented as a new PolishMode (.translate(targetLocaleId:)); all
existing call sites are unchanged.

Settings:
- New TranslationPickerRow in the language tab (Toggle + 10-locale
  picker: en/zh-Hans/zh-Hant/ja/ko/fr/de/es/ru/pt), persisted to the
  App Group so the keyboard extension can read it during live dictation.
- 5 new strings per language (en + zh-Hans).

Keyboard:
- New TranslationChip on the top bar to the right of LocaleChip;
  same Menu pattern, lets users toggle or quickly switch target
  language without leaving the keyboard.
- PolishingService dispatches .translate with a parameterised prompt
  (en/zh variants selected by provider id); PolishingService.error
  gains a translationNotAvailable case so local-engine users get a
  clear inline warning when the toggle is on but cloud is off.
- 6 new strings per language (en + zh-Hans) for the chip + banner.

Local engine policy:
- Translation is cloud-only by design (local engine stays ASR-only
  to honour the no-roundtrip promise). Chip shows a 'cloud required'
  state and raw transcript still inserts on failure — no data loss.

Build:
- OSGKeyboardShared adds TranslationLanguage enum (10 locales) and
  TranslationPrompt factory.
- 4 new files, 9 modified. xcodebuild scheme=OSGKeyboard
  config=Debug destination=iPhone 17 Simulator: BUILD SUCCEEDED
  (0 warning, 0 error).

Also pins DEVELOPMENT_TEAM in project.yml for TestFlight uploads
(3 targets; Team X329MZU23S).
This commit is contained in:
2026-06-25 12:45:44 +08:00
parent dc9697bf3d
commit deddb49d56
17 changed files with 620 additions and 6 deletions
+10
View File
@@ -128,6 +128,9 @@ targets:
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: NO
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD: NO
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
# TestFlight upload: Automatic signing picks the right App Store profile.
CODE_SIGN_STYLE: Automatic
DEVELOPMENT_TEAM: X329MZU23S
dependencies:
- target: OSGKeyboardShared
embed: true
@@ -192,6 +195,9 @@ targets:
SUPPORTS_MACCATALYST: NO
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: NO
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD: NO
# TestFlight upload: Automatic signing picks the right App Store profile.
CODE_SIGN_STYLE: Automatic
DEVELOPMENT_TEAM: X329MZU23S
dependencies:
- target: OSGKeyboardShared
embed: false
@@ -223,6 +229,10 @@ targets:
DYLIB_INSTALL_NAME_BASE: "@rpath"
APPLICATION_EXTENSION_API_ONLY: YES
ENABLE_MODULE_VERIFIER: YES
# Frameworks inherit the host app's signing identity; no profile
# is required, but pinning the team keeps the build reproducible.
CODE_SIGN_STYLE: Automatic
DEVELOPMENT_TEAM: X329MZU23S
dependencies:
- sdk: Speech.framework
- sdk: AVFoundation.framework