Skip to content

fix(web): support autocorrection of transposed text - #16450

Merged
jahorton merged 7 commits into
masterfrom
fix/web/support-transposition-autocorrect
Sep 16, 2026
Merged

jahorton merged 7 commits into
masterfrom
fix/web/support-transposition-autocorrect

Conversation

@jahorton

@jahorton jahorton commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Fixes: #16398
Fixes: #16399
Fixes: #12311

Note: will not handle transpositions that cross token boundaries.

Also note: major changes will be needed for epic/boundary-correction, as it will discontinue use of the LegacyQuotientSpur type.

Build-bot: skip release:web,android,ios

User Testing

TEST_TEH: Using Keyman for Android, type teh and verify that the shows up as a suggestion and is autoselected.

TEST_TEHRE: Using Keyman for Android, type tehre and verify that there shows up as a suggestion and is autoselected.

TEST_FREI: Using Keyman for Android, type frei and verify that friend shows up as a suggestion. (Autoselection is not expected here.)

Fixes: #16398
Fixes: #12311

Note:  will not handle transpositions that cross token boundaries.
Also note:  major changes will be needed for epic/boundary-correction, as it will discontinue use of the LegacyQuotientSpur type.

Build-bot: skip release:web,android,ios
@keymanapp-test-bot keymanapp-test-bot Bot added the user-test-missing User tests have not yet been defined for the PR label Aug 27, 2026
@github-project-automation github-project-automation Bot moved this to Todo in Keyman Aug 27, 2026
@keymanapp-test-bot

keymanapp-test-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

User Test Results

Test specification and instructions

Retesting Template
Test-bot: retest TEST_TEH

Test Artifacts

@keymanapp-test-bot keymanapp-test-bot Bot added this to the A19S36 milestone Aug 27, 2026
@keymanapp-test-bot keymanapp-test-bot Bot added has-user-test user-test-required User tests have not been completed and removed user-test-missing User tests have not yet been defined for the PR labels Aug 27, 2026
@jahorton jahorton linked an issue Aug 27, 2026 that may be closed by this pull request
@keyman-server keyman-server modified the milestones: A19S36, B19S1 Aug 30, 2026
Co-authored-by: Marc Durdin <marc@durdin.net>
@Meng-Heng

Copy link
Copy Markdown
Contributor

Test Specs

  1. Keyman for Android v19.0.272-alpha-test-16450
  2. Pixel 3a XL API 28, Android 9.0
  3. EuroLatin (SIL) keyboard is used for this test with its lexical model.

Test Results

  • TEST_TEH (FAILED):
  1. Type teh
  2. FAILED: rehab shows up
  3. Click Enter to go to a new line
  4. Type teh
  5. VERIFIED: the shows up as a suggestion and is autoselected.
Screen.Recording.2026-09-01.at.11.25.01.in.the.morning.mov
  • TEST_TEHRE (PASSED):
  1. type tehre
  2. VERIFIED: there shows up as a suggestion and is autoselected.
  • TEST_FREI (PASSED):
  1. type frei
  2. VERIFIED: friend shows up as a suggestion, not autoselected.
  3. The autoselected word is freight.

@keymanapp-test-bot keymanapp-test-bot Bot added user-test-failed and removed user-test-required User tests have not been completed labels Sep 1, 2026
Base automatically changed from change/web/narrow-autoselection-comparisons to master September 3, 2026 13:16
@jahorton

jahorton commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

OK, I've made some adjustments. Mind giving it a retry?

Test-bot: retest TEST_TEH

@keymanapp-test-bot keymanapp-test-bot Bot added user-test-required User tests have not been completed and removed user-test-failed labels Sep 4, 2026
@Meng-Heng

Meng-Heng commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Test Specs

  1. Keyman for Android v19.0.279-alpha-test-16450
  2. Pixel 3a XL API 28, Android 9.0
  3. EuroLatin (SIL) keyboard is used for this test with its lexical model.

Test Results

  • TEST_TEH (FAILED):
  1. Type teh
  2. FAILED: rehab shows up
  3. Click Space to apply the auto-highlighted suggestion -> Press Enter for a new line
  4. Type teh
  5. FAILED: rehab shows up as a suggestion and is autoselected
  6. More attempts are shown in the video. This time 'rehab' consistently showing up as the suggestion.
Screen.Recording.2026-09-08.at.4.01.30.in.the.afternoon.mov

@keymanapp-test-bot keymanapp-test-bot Bot added user-test-failed and removed user-test-required User tests have not been completed labels Sep 8, 2026
@jahorton

jahorton commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

I am unable to reproduce the effects you're seeing when using the downloaded artifact when emulating the test device you mentioned on my Mac. (Predictive-text won't even run properly, with errors being thrown!) Interestingly, it seems to operate fine when emulating it on Windows... and only then do I see the issue. Targeting a more up-to-date Android device seems to work much better.

Could you retest against an API 32 (or more recent) Android device and see if the same issue reproduces then?

@Meng-Heng

Copy link
Copy Markdown
Contributor

That's interesting to know, Josh. I'll try it out on a new API, and a physically device, if needed.

@Meng-Heng

Meng-Heng commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Test Specs

  1. Keyman for Android v19.0.279-alpha-test-16450
  2. Pixel 6a API 33, Android 13.0
  3. EuroLatin (SIL) keyboard is used for this test with its lexical model.

Test Results

  • TEST_TEH (FAILED):
  1. Type teh
  2. FAILED: rehab shows up as the suggestion and auto-highlighted
  3. Click Enter to go to a new line
  4. Type teh
  5. VERIFIED: the shows up as the suggestion and auto-highlighted
  6. Type teh
  7. FAILED: team shows up as the suggestion and auto-highlighted.

Test Specs

  1. Keyman for Android v19.0.279-alpha-test-16450
  2. Pixel Tablet API 35, Android 15.0
  3. EuroLatin (SIL) keyboard is used for this test with its lexical model.

Test Results

  • TEST_TEH (FAILED):
  1. Type teh
  2. FAILED: rehab shows up as the suggestion and auto-highlighted
  3. Click Enter to go to a new line
  4. Type teh
  5. VERIFIED: the shows up as the suggestion and auto-highlighted
  6. Type teh
  7. FAILED: team shows up as the suggestion and auto-highlighted.

I'll try testing on Windows one more time, and then move to a physical device.

Update: It's showing the same behavior and result on Windows Android Studio.

@keyman-server keyman-server modified the milestones: B19S1, B19S2 Sep 12, 2026
@Meng-Heng

Copy link
Copy Markdown
Contributor

Test Specs

  1. Keyman for Android v19.0.279-alpha-test-16450
  2. OPPO A60 Android 16
  3. EuroLatin (SIL) keyboard is used for this test with its lexical model.

The same error suggestion is also happening on a physical device:

Recording_20260914_114810.mp4

However, I got some errors popping up on the physical android device:

Warning

"Failed to retrieve downloaded file"
"Failed to access the server!"

Recording_20260914_115352.mp4

@mcdurdin

Copy link
Copy Markdown
Member

However, I got some errors popping up on the physical android device:

Warning

"Failed to retrieve downloaded file" "Failed to access the server!"

I suspect that this may be the user-visible symptoms of #13862

@jahorton

Copy link
Copy Markdown
Contributor Author

However, I got some errors popping up on the physical android device:
Warning
"Failed to retrieve downloaded file" "Failed to access the server!"

I suspect that this may be the user-visible symptoms of #13862

Investigating both error-message strings and looking through recent Sentry error reports... we have nothing matching these errors or the video displaying them in our Sentry logs. A search for reports in the test environment made within the past 48 hours turns up nothing. Nothing shows up against 19.0.279-alpha-test-16450, the most recent build as of that video.

"Failed to retrieve downloaded file"

  • R.string.failed_to_retrieve_file

This would occur when attempting to migrate a local KMP file into the Keyman app's file-organization pattern, like when installing an ad-hoc KMP or when installing from online. Examining its locations in the code, we shouldn't see a reported error for this.

I could perhaps see this happening if the download attempt saw an internet connectivity disruption that interrupted a download partway?

"Failed to access the server!"

  • R.string.update_check_unavailable

This would occur when trying and failing to check for package updates or when attempting to download a keyboard.

@mcdurdin

Copy link
Copy Markdown
Member

Good investigation @jahorton, sorry for the misdirection in my guess!

@jahorton

jahorton commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

After further investigation and brainstorming, I realized a potential cause we've run into once before. Back when epic/gestures was wrapping up, we saw a lot of performance and keys-out-of-sequence bugs on Android devices, which were due to their generally lower performance profile.

Modeling fat-fingering for transpositions incurs a noticeable "edit distance cost" that penalizes a potential search path. If performance were to be low enough that the search never actually is able to investigate the affected transposition nodes, it would appear as if transpositions aren't being handled by the engine. So... what if the issue here is actually an optimization issue?

After a bit of interactive debugging, I realized that the code, as it was, could set up cases where transposition path modeling could overlap with path modeling that involves a sequence of other edit types:

  • suppose the input is cna. can is a reasonable transposition to model, costing one edit.
  • suppose the input is cna. cat is not.
    • We can already model this by deleting the n and adding a t at the end - two edits.
    • The code, as it was, could also try transposing the n and the a, then replacing the n with a t - also two edits.

I verified that such cases were happening and have added new changes (in the latest commit above) that block the transpose-and-replace path from adding redundant search paths. The fewer low-cost, redundant / dead paths there are to search, the easier it will be for correction-search to fully evaluate proper transposition-modeling paths.

@jahorton

Copy link
Copy Markdown
Contributor Author

Oh, and...

Test-bot: retest TEST_TEH

🤞

@Meng-Heng

Copy link
Copy Markdown
Contributor

Test Specs

  1. Keyman for Android v19.0.279-alpha-test-16450
  2. Pixel 6a API 33, Android 13.0
  3. EuroLatin (SIL) keyboard is used for this test with its lexical model.

Test Results

  • TEST_TEH (PASSED):
  1. Type teh

  2. VERIFIED:

    • Initial suggestion: the rehab seem to always suggested first
    • Most of the time: the the shows up as the suggestion and auto-highlighted
    • Rare cases: there is no suggestion and auto-highlighted word
  3. It is definitely more stable than before. After the first the suggestion appear, the consistently appears.

  4. Please see the attached video to evaluate the test result:

    Screen.Recording.2026-09-16.at.10.18.38.in.the.morning.mov
  5. The behavior of suggestion seems to me that rehab get to appear first, and then the after? This behavior happens every time the app is dismissed, and then relaunch.

    Screen.Recording.2026-09-16.at.10.20.53.in.the.morning.mov
  6. If the app isn't dismissed, it remembers to suggest the

    Screen.Recording.2026-09-16.at.10.23.21.in.the.morning.mov

@jahorton
jahorton merged commit 13ae31e into master Sep 16, 2026
10 of 11 checks passed
@jahorton
jahorton deleted the fix/web/support-transposition-autocorrect branch September 16, 2026 18:33
@github-project-automation github-project-automation Bot moved this from Todo to Done in Keyman Sep 16, 2026
@keyman-server

Copy link
Copy Markdown
Collaborator

Changes in this pull request will be available for download in Keyman version 19.0.287-alpha

pull Bot pushed a commit to soitun/keyman that referenced this pull request Sep 21, 2026
Fixes: keymanapp#16577

From 14.0 up until now, our correction-search focused on the minimum "correction distance" to a possible text _correction_, then performed prediction _on top of that_.  This PR changes the search to integrate word-frequency weighting from models within the search, allowing us to optimize for the most likely predictions.  There is no additional performace cost impact of note here - the probability associated with a correction's best prediction is already accessible O(1) with operations we've already been doing.

It is likely that this will help further mitigate issues with transposition handling noted in the user tests for keymanapp#16450.

Build-bot: skip release:web,android,ios
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

4 participants