hermes - ✅(Solved) Fix [Bug]: TUI /model with trailing space skips ModelPicker, custom providers missing from completions [1 pull requests, 2 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#13621Fetched 2026-04-22 08:05:15
View on GitHub
Comments
2
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
commented ×2labeled ×2

Error Message

Custom providers from config.yaml

try: from hermes_cli.config import load_config cfg = load_config() custom_providers = cfg.get("custom_providers") if isinstance(cfg.get("custom_providers"), list) else [] for entry in custom_providers: if not isinstance(entry, dict): continue provider_name = (entry.get("name") or "").strip() if not provider_name: continue models = entry.get("models") if isinstance(models, dict): model_ids = list(models.keys()) elif isinstance(models, list): model_ids = list(models) else: default_model = (entry.get("model") or "").strip() model_ids = [default_model] if default_model else [] for mid in model_ids: mid_stripped = mid.strip() if not mid_stripped or mid_stripped in seen: continue seen.add(mid_stripped) if mid_stripped.lower().startswith(sub_lower): yield Completion( mid_stripped, start_position=-len(sub_text), display=mid_stripped, display_meta=f"custom:{provider_name.lower().replace(' ', '-')}", ) except Exception: pass

Fix Action

Fix / Workaround

Suggested Patches

PR fix notes

PR #14381: feat(cli): make /model autocomplete provider-aware

Description (problem / solution / changelog)

Summary

  • Build /model autocomplete suggestions from authenticated provider catalogs instead of static alias lists.
  • Emit deterministic completions as <model> --provider <provider_slug> so duplicate model names across providers stay clear.
  • Wire the same provider-aware completion behavior through classic CLI and TUI slash completion.
  • Add regression coverage for authenticated-only model completions and provider disambiguation.

Closes #14352. Related to #13621 and prior autocomplete work in #1641.

Testing

  • source venv/bin/activate && python -m py_compile hermes_cli/commands.py cli.py tui_gateway/server.py
  • cd ui-tui && npm run type-check
  • cd ui-tui && npm run lint
  • source venv/bin/activate && python -m pytest tests/hermes_cli/test_ollama_cloud_auth.py::TestModelTabCompletion tests/hermes_cli/test_commands.py::TestSlashCommandCompleter tests/test_tui_gateway_server.py::test_complete_slash_surfaces_completer_error -q -n 4 — 16 passed
  • source venv/bin/activate && python -m pytest tests/hermes_cli/test_commands.py tests/hermes_cli/test_ollama_cloud_auth.py tests/test_tui_gateway_server.py -q -n 4 — 199 passed
  • Manual smoke test: verified /model sonnet and /model gpt-5.4 autocomplete now return concrete model --provider slug options from authenticated providers.

Full-suite note

  • scripts/run_tests.sh ... could not run in my local venv because venv/bin/python has no pip, and the wrapper tries to install pytest-split.
  • I ran the full suite directly with source venv/bin/activate && python -m pytest tests/ -q -n 4; it reported 76 failed, 14683 passed, 53 skipped.
  • I also ran the same direct full-suite command in a clean detached upstream/main worktree at fa8f0c6f, which produced the same 76 failed, 14683 passed, 53 skipped result. The full-suite failures appear to be pre-existing/local baseline failures, not introduced by this branch.

Changed files

  • cli.py (modified, +12/-0)
  • hermes_cli/commands.py (modified, +110/-29)
  • tests/hermes_cli/test_ollama_cloud_auth.py (modified, +47/-48)
  • tests/test_tui_gateway_server.py (modified, +46/-0)
  • tui_gateway/server.py (modified, +70/-1)
  • ui-tui/src/hooks/useCompletion.ts (modified, +14/-8)

Code Example

-      if (!arg) {
+      if (!arg || !arg.trim()) {

---

# Custom providers from config.yaml
try:
    from hermes_cli.config import load_config
    cfg = load_config()
    custom_providers = cfg.get("custom_providers") if isinstance(cfg.get("custom_providers"), list) else []
    for entry in custom_providers:
        if not isinstance(entry, dict):
            continue
        provider_name = (entry.get("name") or "").strip()
        if not provider_name:
            continue
        models = entry.get("models")
        if isinstance(models, dict):
            model_ids = list(models.keys())
        elif isinstance(models, list):
            model_ids = list(models)
        else:
            default_model = (entry.get("model") or "").strip()
            model_ids = [default_model] if default_model else []
        for mid in model_ids:
            mid_stripped = mid.strip()
            if not mid_stripped or mid_stripped in seen:
                continue
            seen.add(mid_stripped)
            if mid_stripped.lower().startswith(sub_lower):
                yield Completion(
                    mid_stripped,
                    start_position=-len(sub_text),
                    display=mid_stripped,
                    display_meta=f"custom:{provider_name.lower().replace(' ', '-')}",
                )
except Exception:
    pass
RAW_BUFFERClick to expand / collapse

Bug Description

Two related issues with the /model command in TUI (hermes --tui):

1. /model (with trailing space) skips ModelPicker

When typing /model and pressing Enter, the TUI autocomplete system appends a space, turning the input into /model . The current logic in session.ts checks if (!arg), but arg is now " " (a space string), which is truthy. This causes it to skip the ModelPicker and fall through to config.set, which fails silently.

Fix: Change if (!arg) to if (!arg || !arg.trim()) at ui-tui/src/app/slash/commands/session.ts:67.

2. Custom providers missing from /model completions

SlashCommandCompleter._model_completions() only yields completions from model_aliases (config) and MODEL_ALIASES (built-in). Models defined under custom_providers in config.yaml are completely absent from the autocomplete list.

Fix: After yielding built-in aliases, also iterate custom_providers from config and yield their models as completions.

Reproduction

  1. Configure custom_providers in ~/.hermes/config.yaml
  2. Start hermes --tui
  3. Type /model and press Enter → expected: ModelPicker opens; actual: nothing happens (or falls through)
  4. Type /model → custom provider models are not in the completion list

Environment

  • Hermes Agent: 0.10.0 (2026.4.16)
  • Platform: Linux (OrbStack VM)
  • TUI mode

Suggested Patches

session.ts (line 67)

-      if (!arg) {
+      if (!arg || !arg.trim()) {

commands.py (_model_completions, after built-in aliases loop)

# Custom providers from config.yaml
try:
    from hermes_cli.config import load_config
    cfg = load_config()
    custom_providers = cfg.get("custom_providers") if isinstance(cfg.get("custom_providers"), list) else []
    for entry in custom_providers:
        if not isinstance(entry, dict):
            continue
        provider_name = (entry.get("name") or "").strip()
        if not provider_name:
            continue
        models = entry.get("models")
        if isinstance(models, dict):
            model_ids = list(models.keys())
        elif isinstance(models, list):
            model_ids = list(models)
        else:
            default_model = (entry.get("model") or "").strip()
            model_ids = [default_model] if default_model else []
        for mid in model_ids:
            mid_stripped = mid.strip()
            if not mid_stripped or mid_stripped in seen:
                continue
            seen.add(mid_stripped)
            if mid_stripped.lower().startswith(sub_lower):
                yield Completion(
                    mid_stripped,
                    start_position=-len(sub_text),
                    display=mid_stripped,
                    display_meta=f"custom:{provider_name.lower().replace(' ', '-')}",
                )
except Exception:
    pass

extent analysis

TL;DR

Apply the suggested patches to session.ts and commands.py to fix the /model command issues in the TUI.

Guidance

  • Update the session.ts file at line 67 to check for trimmed input arguments using if (!arg || !arg.trim()) to prevent skipping the ModelPicker.
  • Modify the _model_completions function in commands.py to include custom provider models from config.yaml in the autocomplete list.
  • Verify the fixes by running the reproduction steps and checking that the ModelPicker opens correctly and custom provider models are included in the completion list.
  • Ensure that the custom_providers configuration in config.yaml is correctly formatted and loaded.

Example

The provided patch for session.ts is:

-      if (!arg) {
+      if (!arg || !arg.trim()) {

And the patch for commands.py iterates over custom_providers and yields their models as completions.

Notes

The fixes assume that the custom_providers configuration is correctly defined in config.yaml and that the hermes_cli.config module can load the configuration correctly.

Recommendation

Apply the workaround by applying the suggested patches to session.ts and commands.py, as they directly address the identified issues and provide a clear solution.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING