Proposal: context-aware learning from accepted and reverted suggestions
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 28/100
Línea de trabajo
Start by reading DictionaryFacilitatorImpl, Suggest, and the existing UserHistoryDictionary mechanisms to understand candidate generation, final ranking, and available storage; the issue does not name specific test files. The proposed first step is rejection feedback: detect an immediate revert, store a bounded negative association, and apply a capped penalty to an existing candidate, with regression tests and no learning in sensitive fields or incognito mode.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Problem
LeanType already has several personalization mechanisms:
UserHistoryDictionary- personal dictionary suggestions
- session word boost
- bigram/trigram history
- configurable personal-suggestion boost
However, these mechanisms mainly learn that a word was used. They do not reliably learn that a particular candidate was the correct choice for a specific mistyped input and context.
For users who mostly enter text by selecting suggestions, this can produce a recurring pattern:
- The intended word is present in the suggestion strip, but ranked second or third.
- The user repeatedly selects it manually.
- The same less suitable candidate remains ranked first on future occurrences.
- A suggestion reverted immediately with Backspace may still remain highly ranked.
This appears related to the personalization balance discussed in #382, but the proposed change would not increase the global weight of personal words.
Proposed direction
Keep the existing dictionary candidate generation unchanged and add a small, bounded feedback layer for suggestion ranking.
Possible feedback signals:
- Selecting suggestion #2 or #3: weak positive feedback for that candidate for the same typed form.
- Repeatedly selecting the same candidate: gradually increase its contextual preference.
- Reverting an autocorrection immediately with Backspace: strong negative feedback for that correction.
- Replacing a selected suggestion immediately: negative feedback for the removed candidate and positive feedback for the replacement.
- Matching previous-word context: allow a larger adjustment than a typed-form-only match.
The feedback should only reorder candidates already produced by the existing dictionaries. It should not generate new words or replace the current decoder.
A simplified model could be:
finalScore = originalScore + contextualFeedbackBoost - rejectionPenalty
The adjustment should be capped so that learned feedback cannot override a clearly better dictionary/spatial match.
Shadow-mode evaluation
Before changing visible suggestions, the candidate ranker could first run in an optional local shadow mode:
baseline order: A, B, C
candidate order: B, A, C
user selected: B
outcome: helped
This would make the feature measurable rather than opaque:
helped: the candidate ranker would move the selected word higher;hurt: the baseline ranked the selected word higher;neutral: no meaningful rank change.
Useful local metrics would include Top-1/Top-3 accuracy, mean reciprocal rank, immediate revert rate, helped vs hurt, and suggestion latency. Visible reranking could remain disabled until enough local evidence shows a meaningful positive margin.
Integration constraints
I would like to keep this compatible with the existing architecture:
- candidate generation remains in
DictionaryFacilitatorImpl; - final suggestion construction remains in
Suggest; - reuse existing user-history mechanisms where practical;
- no network access or telemetry;
- no learning in password fields or incognito mode;
- bounded local storage with decay or eviction;
- no complete-message storage;
- no noticeable latency in the suggestion hot path;
- optional/experimental behavior if it may not be wanted by everyone.
Non-goals
This proposal does not include:
- replacing the AOSP/native dictionary decoder;
- adding an LLM or large neural model;
- introducing a new unified dictionary format;
- changing gesture typing;
- globally increasing the priority of all personal words.
Suggested implementation sequence
PR 1: rejection feedback
Teach LeanType not to repeatedly prefer a suggestion that the user immediately reverted.
This would be intentionally small and independently useful:
- detect immediate revert of an autocorrection or selected suggestion;
- record a bounded negative association;
- apply a capped penalty when the same correction is proposed again;
- add focused regression tests;
- do not learn in sensitive fields or incognito mode.
Candidate generation would remain unchanged; this PR would only apply a bounded penalty to an already generated candidate.
PR 2: accepted-suggestion feedback
After the first behavior is validated:
- learn when the user repeatedly selects a lower-ranked candidate;
- include previous-word context;
- cap and decay old feedback;
- add ranking tests with synthetic candidates and contexts.
Touch-position adaptation could be considered separately only if evidence shows that the intended word is frequently absent from the candidate list rather than merely ranked poorly.
Questions before implementation
- Would a small feedback layer on top of the existing suggestion scores fit the direction of LeanType?
- Should rejection feedback be stored through
UserHistoryDictionary, or would a separate bounded local store be preferable? - Is immediate Backspace after autocorrection a sufficiently reliable rejection signal for the first PR?
- Would you prefer this behind the existing personalized-suggestions setting or a separate experimental toggle?
I can prepare the first narrowly scoped PR after agreeing on the storage and integration point.
- Lenguaje dominante
- Kotlin
- Estrellas
- 1k
- Forks
- 59
- Merge medio
- 13 h 11 min
- PR fusionados (30 d)
- 47
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de LeanBitLab/LeanType
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
LeanBitLab/LeanType#713 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
LeanBitLab/LeanType#423 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Crush ReportAbierto
Dificultad 3/5 1-2 días Aptitud para principiantes 20/100
LeanBitLab/LeanType#715 ·
Los mantenedores suelen responder en 1 día
-
Text Expander/cursor-handling bugPosiblemente ocupada @LeanBitLab la tomó hace 2 días. Abiertobug
Dificultad 3/5 1-2 días Aptitud para principiantes 62/100
LeanBitLab/LeanType#703 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
LeanBitLab/LeanType#699 ·
Los mantenedores suelen responder en 1 día
Todos los issues de LeanBitLab/LeanType
Issues similares
-
area:ide bug platform:intellij
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
anthropics/claude-code#104508 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
lugassawan/swe-workbench#823 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 80/100
Droid-Deck/DroidDeck#1355 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
IronCoreLabs/ironcore-alloy#351 ·