Skip to content

feat(gateway): add /models slash command for model discovery#3503

Open
dlkakbs wants to merge 3 commits intoNousResearch:mainfrom
dlkakbs:feat/models-slash-command
Open

feat(gateway): add /models slash command for model discovery#3503
dlkakbs wants to merge 3 commits intoNousResearch:mainfrom
dlkakbs:feat/models-slash-command

Conversation

@dlkakbs
Copy link
Copy Markdown
Contributor

@dlkakbs dlkakbs commented Mar 28, 2026

What does this PR do?

Adds a /models slash command for first-class model discovery from any gateway surface (Telegram, Discord, CLI, etc.).

Usage:

  • /models — list models for the currently active provider
  • /models — list models for a named provider (openai, anthropic, nous, openrouter, …)
  • /models custom:lmstudio — list models from a named custom OpenAI-compatible endpoint defined in custom_providers

Output behavior:

  • Plain text, one model per line — readable in messaging contexts
  • Currently active model marked with ← active
  • Lists truncated at 50 with remaining count shown (…and N more)
  • Live /models endpoint queried first; falls back to static catalog if unreachable
  • Footer includes the correct /model : switch command

Implementation:

  • CommandDef("models", ...) added to COMMAND_REGISTRY in hermes_cli/commands.py
  • _handle_models_command() added to GatewayRunner in gateway/run.py
  • Wired into the slash command dispatch alongside /provider, /help, etc.
  • Builds on existing provider_model_ids(), curated_models_for_provider(), and fetch_api_models() — no new network logic

Related Issue

Closes #3500

Type of Change

  • New feature (non-breaking change that adds functionality)

Changes Made

  • hermes_cli/commands.py — CommandDef("models", ...) added to registry
  • gateway/run.py — dispatch entry + _handle_models_command() implementation
  • tests/gateway/test_models_command.py — 10 unit tests covering all paths

What's not in this PR and why

/model follow-up integration (e.g. tappable model names that auto-fill /model anthropic:claude-sonnet-4-5):
This would require platform-specific inline keyboard or button support (Telegram InlineKeyboardMarkup, Discord components). Each platform has a different API for interactive elements. Adding this correctly is a separate feature with significant per-platform scope — and /models is already useful without it since the footer tells the user exactly what to type.

Named custom provider syntax improvements (/models custom:work, space-tolerant matching, etc.):
Basic custom: is supported and tested. Edge cases like fuzzy name matching, listing all configured custom providers, or showing metadata (base URL, auth status) were left out to keep scope contained. These are straightforward follow-ups once the base command is in use and real UX feedback exists.

How to Test

  1. Configure a provider (e.g. anthropic) and run /models — confirm the active model is marked.
  2. Run /models openai — confirm a model list is returned.
  3. Add a custom_providers entry in config.yaml and run /models custom: — confirm models are fetched from the endpoint.
  4. Run /models custom:doesnotexist — confirm a clear error message is returned.
  5. Use a provider with 50+ models (e.g. openrouter) — confirm truncation and "and N more" message.
  6. Run pytest tests/gateway/test_models_command.py -v — all 10 tests pass.

Checklist

dlkakbs added 3 commits March 28, 2026 10:34
- /models → list models for the active provider
- /models <provider> → list models for a named provider (openai, anthropic, nous, etc.)
- /models custom:lmstudio → list models from a named custom OpenAI-compatible endpoint
- Marks the currently active model with '← active'
- Truncates long lists at 50 with remaining count shown
- Falls back to static catalog when live /models endpoint is unreachable
- Wires into existing provider_model_ids / curated_models_for_provider / fetch_api_models

Closes NousResearch#3500
@malaiwah
Copy link
Copy Markdown
Contributor

malaiwah commented Apr 8, 2026

+1 — cherry-picked all three commits (c11fa2f + 23ed415 + caf5502) onto my fork and deployed. The new /models custom:<name> discovery command works exactly as advertised against a LiteLLM proxy fronting ~9 models (local Qwen + Gemma, Anthropic Claude direct, ChatGPT via OAuth) — listing returns all of them with the active one marked, no conflicts against recent main. This is the cleanest UX for users with one named provider hosting many backend models. Would be great to see this merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: /models slash command for listing available models

2 participants