From c925cc8eb868708c1799c9f7e40345f07a133e51 Mon Sep 17 00:00:00 2001 From: kshitijk4poor Date: Sat, 22 Aug 2026 15:01:48 +0530 Subject: [PATCH 1/2] refactor(discord): derive model-select capacity from the row/option constants Final-review follow-up: replace the bare 75 in the shown-count with _DISCORD_MODEL_SELECT_CAPACITY so it can never desync from what the partitioned menus actually render. --- plugins/platforms/discord/adapter.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/platforms/discord/adapter.py b/plugins/platforms/discord/adapter.py index 818827e889..0ebc2e3cf8 100644 --- a/plugins/platforms/discord/adapter.py +++ b/plugins/platforms/discord/adapter.py @@ -87,6 +87,10 @@ _DISCORD_SELECT_FIELD_LIMIT = 100 # Discord caps a single select menu at 25 options; a View holds at most 5 rows. _DISCORD_SELECT_MAX_OPTIONS = 25 _DISCORD_SELECT_MAX_ROWS = 5 +# Model-select capacity: keep 2 rows for Back/Cancel, fill the rest with selects. +_DISCORD_MODEL_SELECT_CAPACITY = ( + _DISCORD_SELECT_MAX_ROWS - 2 +) * _DISCORD_SELECT_MAX_OPTIONS _DISCORD_BUTTON_LABEL_LIMIT = 80 _DISCORD_ELLIPSIS = "\u2026" _DISCORD_NONCONVERSATIONAL_METADATA_KEYS = frozenset({ @@ -9355,7 +9359,11 @@ def _define_discord_view_classes() -> None: # select menus (up to 3×25 = 75); the old code hard-capped at 25 # and silently dropped the tail (e.g. Nous `:free` Portal picks). total = provider.get("total_models", 0) if provider else 0 - shown = min(len(provider.get("models", [])), 75) if provider else 0 + shown = ( + min(len(provider.get("models", [])), _DISCORD_MODEL_SELECT_CAPACITY) + if provider + else 0 + ) extra = f"\n*{total - shown} more available — type `/model ` directly*" if total > shown else "" await interaction.response.edit_message( From 9154421b11ed3f85583298e4a1e910c2a5a5cec0 Mon Sep 17 00:00:00 2001 From: kshitijk4poor Date: Sat, 22 Aug 2026 15:08:17 +0530 Subject: [PATCH 2/2] refactor(discord): use _DISCORD_SELECT_MAX_OPTIONS in ChoicePickerView Final-review follow-up: swap the bare [:25] slice for the new constant. Behavior-identical (same 25); removes the last bare option-cap literal in the file. ChoicePickerView feeds finite /reasoning and /fast choice lists, so no functional change. --- plugins/platforms/discord/adapter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/platforms/discord/adapter.py b/plugins/platforms/discord/adapter.py index 0ebc2e3cf8..2ea115b1fb 100644 --- a/plugins/platforms/discord/adapter.py +++ b/plugins/platforms/discord/adapter.py @@ -9537,7 +9537,7 @@ def _define_discord_view_classes() -> None: allowed_role_ids: Optional[set] = None, ): super().__init__(timeout=120) - self.choices = list(choices)[:25] # Discord select cap + self.choices = list(choices)[:_DISCORD_SELECT_MAX_OPTIONS] self.on_choice_selected = on_choice_selected self.allowed_user_ids = allowed_user_ids self.allowed_role_ids = allowed_role_ids or set()