Sort completion candidates by frecency from history - #2158
Open
rolandwalker wants to merge 1 commit into
Open
Conversation
* calculate frecency for tokens in recent history, simply tokenizing and ignoring literals * recalculate frecency in a background thread every N queries at the REPL * sort completion candidates by frecency A good followup could be making the sort-tuple returned by completion_sort_key() configurable.
scottnemes
reviewed
Aug 23, 2026
| return FileHistoryWithTimestamp(history_file) | ||
| configured_history_entries = mycli.config['main'].get('frecency_history_entries', FRECENCY_HISTORY_ENTRIES) | ||
| frecency_history_entries = int(configured_history_entries) if str(configured_history_entries).strip() else 0 | ||
| frecency_refresh_interval = int(mycli.config['main'].get('frecency_refresh_interval', FRECENCY_REFRESH_INTERVAL)) |
Contributor
There was a problem hiding this comment.
Should this have similar if/else logic as frecency_history_entries above?
scottnemes
reviewed
Aug 23, 2026
| return dict(frecency) | ||
|
|
||
|
|
||
| def frecency_score(text: str, frecency: Mapping[str, float]) -> float: |
Contributor
There was a problem hiding this comment.
Potential for caching/memoization if you want to reduce load on larger schemas:
(mycli) arthlo@CAMELOT-2025:~/git/official-mycli$ git diff
diff --git a/mycli/packages/ptoolkit/history.py b/mycli/packages/ptoolkit/history.py
index ba14d38..78b2ba0 100644
--- a/mycli/packages/ptoolkit/history.py
+++ b/mycli/packages/ptoolkit/history.py
@@ -1,5 +1,6 @@
from collections import defaultdict
from collections.abc import Iterable, Mapping
+from functools import lru_cache
from itertools import islice
import logging
import os
@@ -56,12 +57,18 @@ def _calculate_frecency(
return dict(frecency)
-def frecency_score(text: str, frecency: Mapping[str, float]) -> float:
+@lru_cache(maxsize=8192)
+def _frecency_tokens(text: str) -> tuple[str, ...]:
+ """Tokenize a completion candidate. Cached: candidates repeat on every keystroke."""
try:
tokens = tokenize(text, dialect='mysql')
except TokenError:
- return 0.0
- normalized_tokens = [normalized for token in tokens if (normalized := _normalize_frecency_token(token))]
+ return ()
+ return tuple(normalized for token in tokens if (normalized := _normalize_frecency_token(token)))
+
+
+def frecency_score(text: str, frecency: Mapping[str, float]) -> float:
+ normalized_tokens = _frecency_tokens(text)
if not normalized_tokens:
return 0.0
return sum(frecency.get(token, 0.0) for token in normalized_tokens) / len(normalized_tokens)
scottnemes
approved these changes
Aug 23, 2026
scottnemes
left a comment
Contributor
There was a problem hiding this comment.
Added two comments for potential improvements if desired
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.
Description
A good followup could be making the sort-tuple returned by
completion_sort_key()configurable.Fixes #351.
Checklist
changelog.mdfile.AUTHORSfile (or it's already there).