Skip to content

refactor(web): move and rename SearchResult as TokenResultMapping 🚂#15814

Open
jahorton wants to merge 3 commits intoepic/autocorrectfrom
refactor/web/move-and-rename-SearchResult
Open

refactor(web): move and rename SearchResult as TokenResultMapping 🚂#15814
jahorton wants to merge 3 commits intoepic/autocorrectfrom
refactor/web/move-and-rename-SearchResult

Conversation

@jahorton
Copy link
Copy Markdown
Contributor

@jahorton jahorton commented Apr 2, 2026

This is the first of four PRs designed to, in sequence, add an abstraction layer to the correction-search algorithm so that we can use the same core code to search for corrections in different ways.

In particular, up until now, we've always searched for corrections for just one token at a time - the current token. To better support whitespace fat-fingering, we'll need the ability to answer the following question: "Which tokenization pattern is the closest to matching the current text after corrections?" The core logic of the search is the same, but the backing data will be different - something that abstraction can handle well.

To accomplish the goal of abstracting the core search mechanisms, work will proceed in the following manner:

  1. Relocate the code representing paths through the search graph (before making further changes).
  2. Properly return the type representing the critical metadata for processing partial + completed paths of the search graph.
  3. Prepare the search method for abstraction, extracting any code specific to the existing search pattern that may not work well when searching for corrections in alternative ways.
  4. Abstractify the actual search method and critical metadata types.

Build-bot: skip build:web
Test-bot: skip

@keymanapp-test-bot
Copy link
Copy Markdown

keymanapp-test-bot Bot commented Apr 2, 2026

User Test Results

Test specification and instructions

User tests are not required

Test Artifacts

  • Web
    • KeymanWeb Test Home - build : all tests passed (no artifacts on BuildLevel "build")

@keymanapp-test-bot keymanapp-test-bot Bot changed the title refactor(web): move and rename SearchResult as TokenResultMapping refactor(web): move and rename SearchResult as TokenResultMapping 🚂 Apr 2, 2026
@keymanapp-test-bot keymanapp-test-bot Bot added this to the A19S26 milestone Apr 2, 2026
@jahorton jahorton changed the base branch from change/web/suggestion-range to refactor/web/build-and-map-predictions April 9, 2026 21:35
@jahorton jahorton force-pushed the refactor/web/move-and-rename-SearchResult branch from c92585c to 77b8af2 Compare April 9, 2026 21:36
@jahorton jahorton requested a review from ermshiperete April 9, 2026 21:52
@jahorton jahorton marked this pull request as ready for review April 9, 2026 21:52
@keyman-server keyman-server modified the milestones: A19S26, A19S27 Apr 14, 2026
Base automatically changed from refactor/web/build-and-map-predictions to epic/autocorrect April 20, 2026 20:05
Copy link
Copy Markdown
Contributor

@ermshiperete ermshiperete left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. One comment with a potential bug devin.ai identified - the current code is probably correct with the upcoming changes, but thought I'd point it out.

currentReturns[node.resultKey] = node;
// Do not track yielded time.
return new SearchResult(node, newResult.spaceId);
return new TokenResultMapping(newResult.finalNode);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin.ai marked this as a potential bug. I can see that this might become a problem if newResult.finalNode.spaceId != newResult.spaceId can ever happen.

Dropped spaceId argument in getBestMatches during rename refactoring

The refactoring from SearchResult to TokenResultMapping in getBestMatches dropped the explicit newResult.spaceId argument. The old code was new SearchResult(node, newResult.spaceId) but the new code is new TokenResultMapping(newResult.finalNode), which falls back to node.spaceId via the constructor default. When a SearchQuotientCluster is the search module, SearchQuotientCluster.handleNextNode() overrides the result's spaceId to this.spaceId (the cluster's own ID) at search-quotient-cluster.ts:148, which differs from finalNode.spaceId (the child spur's ID). The downstream consumer at predict-helpers.ts:539 uses match.spaceId to look up the correct tokenization via tokenizations.find(t => t.spaceId == match.spaceId) — a wrong spaceId would cause tokenization to be undefined, leading to errors in buildAndMapPredictions. In the current production flow, only LegacyQuotientSpur/LegacyQuotientRoot are passed directly (where node.spaceId == result.spaceId), so the bug is latent, but the semantic contract is broken and would fail if SearchQuotientCluster is ever used as a direct search module.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note #15861 - I'm working to resolve that, though it'll become its own PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants