Skip to content

Commit 20f98cb

Browse files
authored
Implement Favorite Models Feature (#92)
Fixes #90 Favorite AI models by focusing on the list and using `Shift+Space` or the context menu. Favorites appear at the top.
1 parent d045142 commit 20f98cb

File tree

2 files changed

+65
-31
lines changed

2 files changed

+65
-31
lines changed

addon/globalPlugins/openai/apikeymanager.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
AVAILABLE_PROVIDERS = [
44
"OpenAI",
5-
"OpenRouter",
6-
"MistralAI"
5+
"MistralAI",
6+
"OpenRouter"
77
]
88

99
_managers = {}
@@ -24,7 +24,7 @@ def __init__(
2424
self.data_dir = data_dir
2525
self.provider = provider
2626
self.api_key_path = os.path.join(
27-
data_dir,
27+
data_dir,
2828
f"{provider}.key"
2929
)
3030
self.api_key_org_path = os.path.join(

addon/globalPlugins/openai/maindialog.py

Lines changed: 62 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,6 @@ def __init__(
546546
)
547547
self.previousPrompt = None
548548
self._lastSystem = None
549-
self._model_ids = [model.id for model in self._models]
550549
if self.conf["saveSystem"]:
551550
# If the user has chosen to save the system prompt, use the last system prompt used by the user as the default value, otherwise use the default system prompt.
552551
if "system" in self.data:
@@ -727,25 +726,7 @@ def __init__(
727726
self.modelsListCtrl.Bind(wx.EVT_CONTEXT_MENU, self.onModelContextMenu)
728727
self.modelsListCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onModelContextMenu)
729728
self.modelsListCtrl.Bind(wx.EVT_RIGHT_UP, self.onModelContextMenu)
730-
731-
for i, model in enumerate(self._models):
732-
self.modelsListCtrl.InsertItem(i, model.name)
733-
self.modelsListCtrl.SetItem(i, 1, model.provider)
734-
self.modelsListCtrl.SetItem(i, 2, model.id)
735-
self.modelsListCtrl.SetItem(i, 3, str(model.contextWindow))
736-
self.modelsListCtrl.SetItem(
737-
i,
738-
4,
739-
str(model.maxOutputToken) if model.maxOutputToken > 1 else ""
740-
)
741-
model_id = conf["modelVision" if self.pathList else "model"]
742-
model_index = self._getModelIndex(model_id)
743-
self.modelsListCtrl.SetItemState(
744-
model_index,
745-
wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED,
746-
wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED
747-
)
748-
self.modelsListCtrl.EnsureVisible(model_index)
729+
self._refreshModelsList()
749730
mainSizer.Add(modelsLabel, 0, wx.ALL, 5)
750731
mainSizer.Add(self.modelsListCtrl, 0, wx.ALL, 5)
751732

@@ -896,12 +877,6 @@ def __init__(
896877
self.Bind(wx.EVT_CHAR_HOOK, self.onCharHook)
897878
self.Bind(wx.EVT_CLOSE, self.onCancel)
898879

899-
900-
def _getModelIndex(self, model_id):
901-
return list(self._model_ids).index(model_id) if model_id in self._model_ids else (
902-
list(self._model_ids).index(DEFAULT_MODEL_VISION) if self.pathList else 0
903-
)
904-
905880
def addImageToList(
906881
self,
907882
path,
@@ -1035,11 +1010,65 @@ def showModelDetails(self, evt=None):
10351010
True
10361011
)
10371012

1013+
def _getModelIndex(self, model_id):
1014+
for i, model in enumerate(self._models):
1015+
if model.id == model_id:
1016+
return i
1017+
return -1
1018+
1019+
def _refreshModelsList(self, model_to_select=None):
1020+
self.modelsListCtrl.DeleteAllItems()
1021+
favorite_models = self.data.get("favorite_models", [])
1022+
self._models = sorted(
1023+
self._models,
1024+
key=lambda model: (
1025+
not model.id in favorite_models,
1026+
apikeymanager.AVAILABLE_PROVIDERS.index(model.provider),
1027+
model.id.lower()
1028+
),
1029+
reverse=False
1030+
)
1031+
for i, model in enumerate(self._models):
1032+
self.modelsListCtrl.InsertItem(i, model.name)
1033+
self.modelsListCtrl.SetItem(i, 1, model.provider)
1034+
self.modelsListCtrl.SetItem(i, 2, model.id)
1035+
self.modelsListCtrl.SetItem(i, 3, str(model.contextWindow))
1036+
self.modelsListCtrl.SetItem(
1037+
i,
1038+
4,
1039+
str(model.maxOutputToken) if model.maxOutputToken > 1 else ""
1040+
)
1041+
model_id = model_to_select or self.conf["modelVision" if self.pathList else "model"]
1042+
model_index = self._getModelIndex(model_id)
1043+
if model_index == -1:
1044+
model_index = 0
1045+
self.modelsListCtrl.SetItemState(
1046+
model_index,
1047+
wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED,
1048+
wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED
1049+
)
1050+
self.modelsListCtrl.EnsureVisible(model_index)
1051+
1052+
def onFavoriteModel(self, evt):
1053+
model = self.getCurrentModel()
1054+
if not "favorite_models" in self.data:
1055+
self.data["favorite_models"] = []
1056+
if model.id in self.data.get("favorite_models", []):
1057+
self.data["favorite_models"].remove(model.id)
1058+
else:
1059+
self.data["favorite_models"].append(model.id)
1060+
self.saveData(True)
1061+
self._refreshModelsList(model.id)
1062+
10381063
def onModelKeyDown(self, evt):
10391064
if evt.GetKeyCode() == wx.WXK_SPACE:
1040-
self.showModelDetails()
1065+
if evt.GetModifiers() == wx.MOD_SHIFT:
1066+
self.onFavoriteModel(evt)
1067+
elif evt.GetModifiers() == wx.MOD_NONE:
1068+
self.showModelDetails()
10411069
else:
10421070
evt.Skip()
1071+
10431072
def onSubmit(self, evt):
10441073
if not self.promptTextCtrl.GetValue().strip() and not self.pathList:
10451074
self.promptTextCtrl.SetFocus()
@@ -1660,8 +1689,13 @@ def message(
16601689
def onModelContextMenu(self, evt):
16611690
menu = wx.Menu()
16621691
item_id = wx.NewIdRef()
1663-
menu.Append(item_id, _("Show model details") + " (Space)")
1692+
menu.Append(item_id, _("Show model &details") + " (Space)")
16641693
self.Bind(wx.EVT_MENU, self.showModelDetails, id=item_id)
1694+
isFavorite = self.getCurrentModel().id in self.data.get("favorite_models", [])
1695+
item_id = wx.NewIdRef()
1696+
label = _("Add to &favorites") if not isFavorite else _("Remove from &favorites")
1697+
menu.Append(item_id, f"{label} (Shift+Space)")
1698+
self.Bind(wx.EVT_MENU, self.onFavoriteModel, id=item_id)
16651699
menu.AppendSeparator()
16661700
self.modelsListCtrl.PopupMenu(menu)
16671701
menu.Destroy()

0 commit comments

Comments
 (0)