feat: show model pricing for OpenRouter and Nous Portal providers

Display live per-million-token pricing from /v1/models when listing
models for OpenRouter or Nous Portal. Prices are shown in a
column-aligned table with decimal points vertically aligned for
easy comparison.

Pricing appears in three places:
- /provider slash command (table with In/Out headers)
- hermes model picker (aligned columns in both TerminalMenu and
  numbered fallback)

Implementation:
- Add fetch_models_with_pricing() in models.py with per-base_url
  module-level cache (one network call per endpoint per session)
- Add _format_price_per_mtok() with fixed 2-decimal formatting
- Add format_model_pricing_table() for terminal table display
- Add get_pricing_for_provider() convenience wrapper
- Update _prompt_model_selection() to accept optional pricing dict
- Wire pricing through _model_flow_openrouter/nous in main.py
- Update test mocks for new pricing parameter
This commit is contained in:
emozilla
2026-04-03 18:46:45 -04:00
committed by Teknium
parent 0efe7dace7
commit 0365f6202c
5 changed files with 251 additions and 17 deletions

View File

@@ -1088,10 +1088,13 @@ def _model_flow_openrouter(config, current_model=""):
print("API key saved.")
print()
from hermes_cli.models import model_ids
from hermes_cli.models import model_ids, get_pricing_for_provider
openrouter_models = model_ids()
selected = _prompt_model_selection(openrouter_models, current_model=current_model)
# Fetch live pricing (non-blocking — returns empty dict on failure)
pricing = get_pricing_for_provider("openrouter")
selected = _prompt_model_selection(openrouter_models, current_model=current_model, pricing=pricing)
if selected:
_save_model_choice(selected)
@@ -1158,7 +1161,7 @@ def _model_flow_nous(config, current_model="", args=None):
# Already logged in — use curated model list (same as OpenRouter defaults).
# The live /models endpoint returns hundreds of models; the curated list
# shows only agentic models users recognize from OpenRouter.
from hermes_cli.models import _PROVIDER_MODELS
from hermes_cli.models import _PROVIDER_MODELS, get_pricing_for_provider
model_ids = _PROVIDER_MODELS.get("nous", [])
if not model_ids:
print("No curated models available for Nous Portal.")
@@ -1188,7 +1191,10 @@ def _model_flow_nous(config, current_model="", args=None):
print(f"Could not verify credentials: {msg}")
return
selected = _prompt_model_selection(model_ids, current_model=current_model)
# Fetch live pricing (non-blocking — returns empty dict on failure)
pricing = get_pricing_for_provider("nous")
selected = _prompt_model_selection(model_ids, current_model=current_model, pricing=pricing)
if selected:
_save_model_choice(selected)
# Reactivate Nous as the provider and update config