From c23c7c994bf8b77c513b7c3fb4a68774970e47ac Mon Sep 17 00:00:00 2001 From: Austin Pickett Date: Thu, 30 Apr 2026 23:41:19 -0400 Subject: [PATCH] =?UTF-8?q?fix(tui):=20address=20remaining=20review=20feed?= =?UTF-8?q?back=20=E2=80=94=20ordering=20and=20digit=20shortcuts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- tui_gateway/server.py | 62 +++++++++++++++------------ ui-tui/src/components/modelPicker.tsx | 20 +-------- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 3e7176f9f0..7dad4e7639 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -4736,43 +4736,51 @@ def _(rid, params: dict) -> dict: max_models=50, ) - # Mark authenticated providers and build lookup - authed_slugs = set() + # Mark authenticated providers and build lookup by slug + authed_map: dict = {} + authed_extra: list = [] # user-defined/custom not in CANONICAL_PROVIDERS + canonical_slugs = {e.slug for e in CANONICAL_PROVIDERS} for p in authenticated: p["authenticated"] = True - authed_slugs.add(p["slug"]) + authed_map[p["slug"]] = p + if p["slug"] not in canonical_slugs: + authed_extra.append(p) - # Add unauthenticated canonical providers so the picker shows all - # options (matching `hermes model` behaviour). + # Build final list in CANONICAL_PROVIDERS order, merging auth data from hermes_cli.auth import PROVIDER_REGISTRY as _auth_reg + ordered: list = [] for entry in CANONICAL_PROVIDERS: - if entry.slug in authed_slugs: - continue - pconfig = _auth_reg.get(entry.slug) - auth_type = pconfig.auth_type if pconfig else "api_key" - key_env = pconfig.api_key_env_vars[0] if (pconfig and pconfig.api_key_env_vars) else "" - if auth_type == "api_key" and key_env: - warning = f"paste {key_env} to activate" + if entry.slug in authed_map: + ordered.append(authed_map[entry.slug]) else: - warning = f"run `hermes model` to configure ({auth_type})" - authenticated.append({ - "slug": entry.slug, - "name": _PROVIDER_LABELS.get(entry.slug, entry.label), - "is_current": entry.slug == current_provider, - "is_user_defined": False, - "models": [], - "total_models": 0, - "source": "built-in", - "authenticated": False, - "auth_type": auth_type, - "key_env": key_env, - "warning": warning, - }) + pconfig = _auth_reg.get(entry.slug) + auth_type = pconfig.auth_type if pconfig else "api_key" + key_env = pconfig.api_key_env_vars[0] if (pconfig and pconfig.api_key_env_vars) else "" + if auth_type == "api_key" and key_env: + warning = f"paste {key_env} to activate" + else: + warning = f"run `hermes model` to configure ({auth_type})" + ordered.append({ + "slug": entry.slug, + "name": _PROVIDER_LABELS.get(entry.slug, entry.label), + "is_current": entry.slug == current_provider, + "is_user_defined": False, + "models": [], + "total_models": 0, + "source": "built-in", + "authenticated": False, + "auth_type": auth_type, + "key_env": key_env, + "warning": warning, + }) + + # Append user-defined/custom providers not in canonical list + ordered.extend(authed_extra) return _ok( rid, { - "providers": authenticated, + "providers": ordered, "model": current_model, "provider": current_provider, }, diff --git a/ui-tui/src/components/modelPicker.tsx b/ui-tui/src/components/modelPicker.tsx index 2b3fec0384..45c9bc4cda 100644 --- a/ui-tui/src/components/modelPicker.tsx +++ b/ui-tui/src/components/modelPicker.tsx @@ -8,7 +8,7 @@ import type { ModelOptionProvider, ModelOptionsResponse } from '../gatewayTypes. import { asRpcResult, rpcErrorMessage } from '../lib/rpc.js' import type { Theme } from '../theme.js' -import { OverlayHint, useOverlayKeys, windowItems, windowOffset } from './overlayControls.js' +import { OverlayHint, useOverlayKeys, windowItems } from './overlayControls.js' const VISIBLE = 12 const MIN_WIDTH = 40 @@ -264,24 +264,6 @@ export function ModelPicker({ gw, onCancel, onSelect, sessionId, t }: ModelPicke return } - - const n = ch === '0' ? 10 : parseInt(ch, 10) - - if (!Number.isNaN(n) && n >= 1 && n <= Math.min(10, count)) { - const offset = windowOffset(count, sel, VISIBLE) - - if (stage === 'provider') { - const next = offset + n - 1 - - if (providers[next]) { - setProviderIdx(next) - } - } else if (provider && models[offset + n - 1]) { - onSelect( - `${models[offset + n - 1]} --provider ${provider.slug}${persistGlobal ? ' --global' : ` ${TUI_SESSION_MODEL_FLAG}`}` - ) - } - } }) if (loading) {