Skip to content

feat(tui): overhaul /model picker to match hermes model with inline auth#18117

Merged
austinpickett merged 6 commits into
mainfrom
austin/fix/model-selector
May 1, 2026
Merged

feat(tui): overhaul /model picker to match hermes model with inline auth#18117
austinpickett merged 6 commits into
mainfrom
austin/fix/model-selector

Conversation

@austinpickett

@austinpickett austinpickett commented Apr 30, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Overhauls the TUI /model picker to reach parity with hermes model. Previously the TUI only showed authenticated providers (5-ish), while hermes model showed all 35+ canonical providers. Users couldn't tell what was available or set up new providers without leaving the TUI.

Now:

  • Shows all canonical providers with visual auth indicators ( ready / needs key)
  • Selecting an unauthenticated API-key provider opens an inline masked key input — pastes the key, saves to .env, and transitions directly to model selection
  • Non-API-key auth providers (OAuth, external process) show guidance to run hermes model
  • Fixes a bug where user-defined providers (e.g. ollama) were invisible due to user_providers being passed as a list instead of dict

Related Issue

Fixes TUI/CLI /model parity gap — user-reported: "why does the /model picker behave differently between the cli and TUI? I see my ollama model in /model in the cli but don't see them when I use TUI"

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)

Changes Made

  • tui_gateway/server.py: Fix _apply_model_switch() to pass cfg.get("providers") as dict (not list). model.options now returns all canonical providers with authenticated, auth_type, key_env fields. New model.save_key RPC method for inline credential setup.
  • hermes_cli/model_switch.py: Fix validation-override block (~line 893) to handle user_providers as dict with both dict-keyed and list-format models.
  • ui-tui/src/components/modelPicker.tsx: Full rewrite — 3 stages (provider → key → model), inline masked API key input, absolute row numbering, auth status indicators, dimmed unauthenticated rows.
  • ui-tui/src/gatewayTypes.ts: Added auth_type?, authenticated?, key_env? to ModelOptionProvider.

How to Test

  1. Run hermes --tui and type /model
  2. Verify all canonical providers appear (not just authenticated ones)
  3. Unauthenticated API-key providers show and (no key) — selecting one opens key input
  4. Paste a valid API key → saves to .env → transitions to model list
  5. Pressing Esc from key input returns to provider list
  6. Authenticated providers show with model counts — selecting proceeds to model picker
  7. Scroll the list — verify row numbers reflect actual position (13, 14, 15... not always 1-12)
  8. If you have a user-defined provider in config.yaml under providers: (e.g. ollama), verify it appears

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: WSL2 Ubuntu

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots

image image image

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/tui Terminal UI (ui-tui/ + tui_gateway/) comp/cli CLI entry point, hermes_cli/, setup wizard duplicate This issue or pull request already exists labels Apr 30, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #18085 — same root cause: TUI passes user_providers as wrong type to switch_model().

1 similar comment
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #18085 — same root cause: TUI passes user_providers as wrong type to switch_model().

@austinpickett austinpickett changed the title fix(tui): pass user_providers as dict to match CLI model-switch pipeline feat(tui): overhaul /model picker to match hermes model with inline auth May 1, 2026
@OutThisLife OutThisLife requested review from Copilot and teknium1 May 1, 2026 00:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Overhauls the TUI /model picker to align with hermes model by showing all canonical providers (not just authenticated ones), surfacing auth status, and enabling inline API-key setup from within the TUI.

Changes:

  • Updated gateway model-option typing to include auth metadata (auth_type, authenticated, key_env).
  • Rewrote the TUI ModelPicker into a 3-stage flow (provider → key → model) with auth indicators and absolute row numbering.
  • Extended tui_gateway model RPCs to return unauthenticated canonical providers and added a model.save_key method; fixed user_providers shape handling.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
ui-tui/src/gatewayTypes.ts Extends model provider option types with auth-related fields.
ui-tui/src/components/modelPicker.tsx Implements the new staged picker UI, auth indicators, inline key entry, and absolute numbering.
tui_gateway/server.py Fixes user_providers passing, expands model.options to include unauthenticated canonicals, and adds model.save_key.
hermes_cli/model_switch.py Adjusts model validation override logic to handle providers: dict model lists (dict or list).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tui_gateway/server.py Outdated
Comment thread tui_gateway/server.py Outdated
Comment thread tui_gateway/server.py
Comment thread ui-tui/src/components/modelPicker.tsx
Comment thread ui-tui/src/components/modelPicker.tsx
Comment thread ui-tui/src/components/modelPicker.tsx
Comment thread ui-tui/src/components/modelPicker.tsx
The TUI's _apply_model_switch() was converting the config.yaml
`providers:` dict into a list of dicts before passing it to
switch_model(). This caused resolve_provider_full() →
resolve_user_provider() to fail, since that function expects a dict
and does `user_config.get(name)` to look up provider entries.

The result: user-defined providers (e.g. ollama) appeared in CLI's
/model picker but were invisible in the TUI.

Fix:
- tui_gateway/server.py: pass cfg.get('providers') directly (dict),
  matching what cli.py already does at line 5598.
- hermes_cli/model_switch.py: fix the validation-override block
  (line ~893) which iterated user_providers as a list — now correctly
  handles the dict format with support for both dict-keyed and
  list-format models arrays.
The model picker displayed row numbers 1-12 regardless of scroll
position, making it impossible to tell where you were in the list.
Now shows the actual item index (e.g. 5, 6, 7... when scrolled down).

Also removed '1-9,0 quick' from the hint text since digit shortcuts
still work relative to the visible window, which would be confusing
with absolute numbering.
- model.options now returns all canonical providers (not just
  authenticated), each with authenticated/auth_type/key_env fields
- New model.save_key RPC method: saves API key to .env, sets in
  process, returns refreshed provider with models
- Picker shows ● (authed) / ○ (no key) markers with dimmed styling
- Selecting an unauthenticated api_key provider opens inline masked
  key input — after save, transitions directly to model selection
- Non-api_key auth providers show guidance to run hermes model
- Row numbers now show absolute position in list
…icker

- New model.disconnect RPC method: clears API key env vars from .env
  and OAuth/credential pool state via clear_provider_auth()
- Press 'd' on an authenticated provider opens confirmation prompt
- y/Enter confirms disconnect, n/Esc cancels
- Provider flips to unauthenticated state in-place (re-selectable
  to re-auth by pressing Enter again)
@austinpickett austinpickett force-pushed the austin/fix/model-selector branch from 7851038 to f4c761c Compare May 1, 2026 03:09
- Reset keySaving on back() to prevent blocked key entry after Esc
- Show '(needs setup)' for non-API-key auth providers instead of
  generic '(no key)'
- Set is_current correctly for unauthenticated providers that happen
  to be the active session provider
- Guard model.save_key with is_managed() check — return error on
  managed installs where .env is read-only
…tcuts

- Emit providers in CANONICAL_PROVIDERS order (matching hermes model)
  with user-defined/custom providers appended after
- Remove digit quick-select (1-9,0) handler — inconsistent with
  absolute row numbering and already removed from hint text
- Remove unused windowOffset import
@austinpickett austinpickett merged commit 2013243 into main May 1, 2026
9 of 11 checks passed
@austinpickett austinpickett deleted the austin/fix/model-selector branch May 1, 2026 12:30
jsboige pushed a commit to jsboige/hermes-agent that referenced this pull request May 14, 2026
…del-selector

feat(tui): overhaul /model picker to match hermes model with inline auth
dannyJ848 pushed a commit to dannyJ848/hermes-agent that referenced this pull request May 17, 2026
…del-selector

feat(tui): overhaul /model picker to match hermes model with inline auth
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…del-selector

feat(tui): overhaul /model picker to match hermes model with inline auth
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
…del-selector

feat(tui): overhaul /model picker to match hermes model with inline auth
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 comp/tui Terminal UI (ui-tui/ + tui_gateway/) duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants