fix(translate): auto-language mis-detection made the preview claim ru→en wasn't downloaded - #235
Merged
Merged
Conversation
…→en wasn't downloaded With language=auto the provider detects the source from the TEXT. On the short Cyrillic fragments the live translation preview fires on, NLLanguageRecognizer's top guess is often Ukrainian for Russian speech; uk→en is typically not installed, so the pre-check fail-fasted with 'isn't downloaded — Settings → Dictation has the download' while the user's real ru→en pair was installed and working (the session FINAL, detected over the full text, translated fine — the reported symptom). Fix: for auto sessions, rank the recognizer's hypotheses (max 3) and prefer the best-confidence candidate whose pair with the target is INSTALLED — pure policy TextTranslationPolicy.pickDetectedSource with a 0.15 confidence floor so installed-pair noise can't hijack detection; no installed candidate → honest top guess + the existing fail-fast. A concrete session language still wins outright. Empirically confirmed on this machine: ru→en .installed in all tag forms, uk→en .supported — exactly the divergence reported. Co-Authored-By: Claude <noreply@anthropic.com>
initcore0
added a commit
that referenced
this pull request
Aug 1, 2026
…review (#236) Headline: dictate in one language, get another — translation now runs on the Apple Translation text path (#223), which means it works with EVERY transcription engine including Parakeet (#233), not just the whisper family. Plus an experimental live preview that shows the translation in the overlay while you speak (#231), and the auto-detect fix that stopped it misreporting Russian as an un-downloaded pair (#235). Also: macOS 15 floor + whisper family de-recommended (#233), meetings open in Scratchpad (#229), stream-overlay voice-command counter (#232), and the input-device / streaming-finalize fixes (#224-227). Stats: 60 → 67 changes, 36 → 40 features, tests 1870 → 2009. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
initcore0
added a commit
that referenced
this pull request
Aug 4, 2026
…cratchpad editor (#245) Adds the 2026-08 release entry covering everything shipped after the 2026-07 entry (v1.0.19 → v1.1.0+177), and re-renders changelog.html from the JSON. 18 entries — 9 features, 6 fixes, 3 improvements — verified against `git log v1.0.18+173..v1.1.0+177`, docs/PLUGINS.md, and the manifest in PluginRegistry.swift rather than from PR intent. The lead story is the plugin system (#244 / MAK-100) split into three entries, because "there are plugins now", "the first one makes memes", and "you can drive it hands-free from refine" are three different things a reader needs: - Plugins are opt-in twice over — the pane defaults to nothing enabled, and the entry says so, along with the networkHosts disclosure being a label rather than a sandbox (the honest limit docs/PLUGINS.md states). - The meme entry discloses the only network use: api.imgflip.com, i.imgflip.com and api.memegen.link serve the blank template image; captioning and rendering are local, and imported templates need no network at all. memegen.link's server-side captioning is deliberately unused, and the entry doesn't claim capability the plugin declines. - The voice-command entry spells out both flows (selection vs. spoken remainder), the EN + RU triggers, and the strict prefix/word-boundary matching — the reason "create a memo about Q3" is never eaten. Remaining entries cover the Scratchpad quality editor (MAK-95/96/97), in-note find (#240), AI actions + file-transcript import (MAK-98/99), model-readiness UX (MAK-94), the stream-overlay counter (#232), and the fixes: vocabulary substitutions before translation (#238), ru/uk detection (#235/#238), app-wide ⌘V (#242), per-keystroke Scratchpad saves, "Model: Not checked", and the "in 0s" timestamp. Every `howTo.availability` is "live" — each was checked against the shipping code path, per the truth contract in docs/changelog/README.md. stats.testsPassing = 2685 is the measured `swift test` count on this tree, not a carried-forward number. changelog.html renders only the latest release (its established behavior), so July's entries move out of the reference render and stay canonical in the JSON. The <style> block and page skeleton are byte-identical; only the content under div.wrap is regenerated. Gates: swift test 2685 passing, 0 failures (docs-only change — untouched). Co-authored-by: Claude <noreply@anthropic.com>
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.
Reported: dictating Russian with translate on (language=auto), the overlay showed "Russian → English isn't downloaded — Settings → Dictation has the download" mid-session, yet the released final translated correctly, and the ru→en assets were definitely installed.
Root cause (empirically confirmed via a LanguageAvailability probe on the owner's machine): ru→en is
.installedin every tag form, butuk→enis.supported(-not-downloaded) — and on the short Cyrillic fragments the live preview fires on, NLLanguageRecognizer's top guess for Russian speech is often Ukrainian. The provider's fail-fast then honestly reported the wrong pair. The final, detected over the full text, resolved ru and worked.Fix: for auto sessions, rank the recognizer's hypotheses and prefer the best-confidence candidate whose pair is installed (
TextTranslationPolicy.pickDetectedSource, pure + 6 tests, 0.15 confidence floor so installed-pair noise can't hijack detection). No installed candidate → unchanged behavior. Concrete session language → unchanged behavior.2009 tests green, ratchet OK, clean build.
🤖 Generated with Claude Code