feat(cli): add list_picker_providers for credential-filtered picker#13561
Closed
Tkander1715 wants to merge 1 commit into
Closed
feat(cli): add list_picker_providers for credential-filtered picker#13561Tkander1715 wants to merge 1 commit into
Tkander1715 wants to merge 1 commit into
Conversation
The Telegram/Discord /model pickers currently call list_authenticated_providers(), which returns every provider whose credentials resolve locally and every model in its curated snapshot. Two failure modes fall out: - OpenRouter rows can include IDs the live catalog no longer carries. - Provider rows can surface with zero callable models (e.g. a slug whose credential pool entry exists but has nothing behind it). list_picker_providers() wraps the base function and post-processes the result so the interactive picker only shows models the user can actually select: - OpenRouter's models come from fetch_openrouter_models() (live-catalog filtered against the curated OPENROUTER_MODELS snapshot). - Rows with an empty models list are dropped, except custom endpoints (is_user_defined=True with an api_url) where the user may enter model ids manually. - All other fields pass through unchanged. The gateway /model handler switches to the new helper for the interactive picker payload only. Typed /model <name> and the text fallback list stay on list_authenticated_providers() so nothing is hidden from power users or platforms without a picker. Covered by nine focused unit tests in tests/hermes_cli/test_list_picker_providers.py. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collaborator
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.
What
Adds
list_picker_providers()— a thin wrapper aroundlist_authenticated_providers()that post-processes the result so the interactive/modelpicker (Telegram, Discord) only surfaces models the user can actually call._handle_model_command()ingateway/run.pyswitches to the new helper for the interactive picker payload only.Why
Two failure modes today when a user opens
/model:OPENROUTER_MODELSis a static snapshot. When OpenRouter drops or renames a model upstream between Hermes releases, the picker still offers it; tapping it fails at call time.The filter fixes both without changing
list_authenticated_providers(), which is also consumed by the CLI text fallback where the unfiltered view is arguably still the right default.How it works
openrouterrow,modelsare replaced with the output offetch_openrouter_models(), which already cross-checks the curated snapshot against the live OpenRouter catalog.modelslist are dropped, except custom endpoints (is_user_defined=Truewith anapi_url) where the user may enter model IDs manually.Typed
/model <name>and the text fallback list stay onlist_authenticated_providers(), so nothing is hidden from power users or platforms without an interactive picker.How to test
Nine focused unit tests covering:
modelsrow droppedapi_urlkept when models emptyapi_urland empty models droppedmax_modelscaps OpenRouter live outputManual test: open
/modelin Telegram with a setup that exercises each branch — OpenRouter + a direct provider + a user-defined custom endpoint.Platforms tested
Notes
main(fork was behind by ~800 commits and syncing required aworkflowOAuth scope I didn't have). The three files touched cherry-picked onto currentmaincleanly in my local worktree — happy to rebase on request.