Skip to content

fix(model): sort configured providers first in hermes model wizard - #3227

Open
Mibayy wants to merge 1 commit into
NousResearch:mainfrom
Mibayy:fix/model-wizard-show-configured-providers-3226
Open

fix(model): sort configured providers first in hermes model wizard#3227
Mibayy wants to merge 1 commit into
NousResearch:mainfrom
Mibayy:fix/model-wizard-show-configured-providers-3226

Conversation

@Mibayy

@Mibayy Mibayy commented Mar 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #3226

hermes model showed all providers in a flat alphabetical list regardless of whether the user had credentials for them. Someone with only kimi-coding configured had to scroll past 14 irrelevant entries.

list_available_providers() in hermes_cli/models.py already tested for credentials on every provider and returned an authenticated field — but cmd_model() in main.py never used it. This PR wires them together.

Behaviour change

Before:

Select provider:
  OpenRouter (100+ models, pay-per-use)
  Nous Portal (Nous Research subscription)
  OpenAI Codex
  GitHub Copilot ACP
  GitHub Copilot
  Anthropic
  ...14 entries, no indication which ones are configured...
  Kimi / Moonshot  ← currently active

After:

Select provider:
  Kimi / Moonshot  ← currently active
  ──── unconfigured ────
  OpenRouter (100+ models, pay-per-use)  [not configured]
  Nous Portal (Nous Research subscription)  [not configured]
  OpenAI Codex  [not configured]
  ...

Configured providers float to the top; unconfigured ones are marked [not configured] and listed below. Nothing is hidden — hermes model is also the setup flow for new providers, so all remain selectable.

Implementation

  • Call list_available_providers() once to get auth status for each provider ID.
  • Split provider list into configured and unconfigured during the ordering pass.
  • Active provider always goes first in configured with the existing ← currently active marker.
  • Named custom providers from config.yaml are always treated as configured (they have an explicit base_url).
  • remove-custom sentinel moved to always-last position (was previously appended to the main list before reordering, which worked but was fragile).

Tests

1661 gateway + session + run_agent tests pass, 21 skipped. The 2 pre-existing failures (test_toolset_has_keys_for_vision_accepts_codex_auth, test_custom_setup_clears_active_oauth_provider) reproduce on main without this patch.

hermes model showed all providers in a flat list regardless of whether the
user had credentials for them. For someone with only one provider configured,
this meant scrolling past 14 irrelevant entries to find theirs.

The fix uses the existing list_available_providers() auth-check logic (which
already tested for credentials / login state but was never wired into the
wizard display) to split the provider list into two groups:

  - Configured providers (authenticated=True) listed first, no marker
  - Unconfigured providers listed below with a '[not configured]' suffix

The active provider still floats to position 0 with '<- currently active'.
No providers are hidden — hermes model is also the setup flow for new
providers, so unconfigured ones remain reachable.

Named custom providers (custom_providers in config.yaml) are always treated
as configured since they have an explicit base_url.

Closes NousResearch#3226
@alt-glitch alt-glitch added type/feature New feature or request comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have labels May 2, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for targeting a real model-picker usability gap. The issue remains present on current main: hermes_cli/main.py:3003-3033 constructs the provider picker from all canonical providers and only prioritizes the active row, while hermes_cli/models.py:1672-1713 already exposes per-provider authenticated state.

Problems

  • The patch was written before provider grouping. Current main folds slugs into multi-member rows via group_providers() (hermes_cli/main.py:3003; hermes_cli/models.py:1134-1160), so the flat partition in this diff does not define how a group with mixed credential status should be ordered or labeled.
  • The diff contains no regression test. Existing group behavior is covered in tests/hermes_cli/test_provider_groups.py:63-101.

Suggested changes

  • Rework the ordering at the current group-row layer and define mixed-status group behavior.
  • Add a focused picker test covering configured-first ordering, the active group/provider, unconfigured reachability, and custom/action rows.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
kshitijk4poor pushed a commit that referenced this pull request Sep 2, 2026
…dup + dropped-block notices

content and structuredContent are now alternatives — never both forwarded
to the model. Spec-following servers render their data into content (the
verbatim dual-emit SHOULD or a faithful reorganisation), so forwarding
both sent the same information twice per tool call. structuredContent
fills in only when content blocks render effectively empty (whitespace-only
text counts as empty), preserving structuredContent-only servers. _meta
passthrough is unchanged.

Also surfaces unsupported content-block drops to the MODEL as
'[MCP content dropped: unsupported block (...)]' notices carrying
type/mime/uri/size handles (kimi-code#3227) instead of a log-only warning;
drop notices do not count as usable content for the arbitration.

Live E2E: real stdio MCP server (mcp 2.x structured_output tool) through
register_mcp_servers + _make_tool_handler — origin/main forwarded the
payload twice, branch forwards content only; text-only path unchanged.
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
…edContent dedup + dropped-block notices

content and structuredContent are now alternatives — never both forwarded
to the model. Spec-following servers render their data into content (the
verbatim dual-emit SHOULD or a faithful reorganisation), so forwarding
both sent the same information twice per tool call. structuredContent
fills in only when content blocks render effectively empty (whitespace-only
text counts as empty), preserving structuredContent-only servers. _meta
passthrough is unchanged.

Also surfaces unsupported content-block drops to the MODEL as
'[MCP content dropped: unsupported block (...)]' notices carrying
type/mime/uri/size handles (kimi-code#3227) instead of a log-only warning;
drop notices do not count as usable content for the arbitration.

Live E2E: real stdio MCP server (mcp 2.x structured_output tool) through
register_mcp_servers + _make_tool_handler — origin/main forwarded the
payload twice, branch forwards content only; text-only path unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hermes model 应只显示已配置凭证的 provider

3 participants