Suppress "Credit access paused" notice on free models#43669
Conversation
|
Verification comment from automated review Reviewed the diff. This correctly suppresses the "Credit access paused" notice when the active model is a Nous free-tier model (identified by
The |
alt-glitch
left a comment
There was a problem hiding this comment.
Design is sound — the latch semantics are careful (no spurious "restored" on a free-model switch, depleted re-fires when switching back to a paid model, genuine recovery still emits restored), fail-open direction is right, and the zero-network guarantee is test-enforced. All 54 credits tests pass locally on this branch.
One real defect: the pricing-cache peek never fires at runtime for Nous due to a /v1 cache-key mismatch (inline comment below). The :free-suffix path carries the actual fix today, so the bug is masked rather than harmful — but the cache branch is dead code as written. One-line fix + a test using the agent-shaped base URL and this is good to merge.
| try: | ||
| from hermes_cli.models import _is_model_free, _pricing_cache | ||
|
|
||
| pricing = _pricing_cache.get(base_url.rstrip("/")) |
There was a problem hiding this comment.
Bug: this peek never hits at runtime for Nous — /v1 cache-key mismatch.
The caller passes self.base_url, which for Nous is https://inference-api.nousresearch.com/v1 (hermes_cli/auth.py DEFAULT_NOUS_INFERENCE_URL). But _pricing_cache is keyed without /v1: get_pricing_for_provider("nous") strips a trailing /v1 before calling fetch_models_with_pricing (hermes_cli/models.py, the stripped.endswith("/v1") block), so the cache key is https://inference-api.nousresearch.com.
Verified live:
m._pricing_cache["https://inference-api.nousresearch.com"] = {"some/zero-priced": {"prompt": "0", "completion": "0"}}
is_free_tier_model("some/zero-priced", "https://inference-api.nousresearch.com/v1") # False — agent's base_url
is_free_tier_model("some/zero-priced", "https://inference-api.nousresearch.com") # True — picker's keyFix: mirror the same normalization here, e.g.
key = base_url.rstrip("/")
if key.endswith("/v1"):
key = key[:-3].rstrip("/")
pricing = _pricing_cache.get(key)The existing tests miss this because they pass the already-stripped base — please add a case using the /v1-suffixed URL the agent actually holds.
| assert is_free_tier_model("") is False | ||
| assert is_free_tier_model("Hermes-4-405B") is False | ||
|
|
||
| def test_pricing_cache_peek_zero_priced_model(self, monkeypatch): |
There was a problem hiding this comment.
Worth a note (comment-level, not blocking): even with the key fixed, this cache is only populated when the same process ran the model picker's pricing fetch — gateway sessions never fetch pricing, so suppression there rests entirely on the :free suffix. That's fine in practice (all Nous free SKUs carry :free), but a one-line comment in is_free_tier_model's docstring saying the cache peek is CLI-session best-effort would save the next reader the investigation.
alt-glitch
left a comment
There was a problem hiding this comment.
Both findings addressed in 2dcfdc8 — re-verified empirically:
/v1key mismatch: the original repro (cache seeded under the pre-/v1 root, peek with the agent's/v1-suffixed base_url) now returnsTrue; paid model stillFalse.- Test now exercises the agent-shaped
/v1base URL plus trailing-slash variants, so a regression in the normalization would be caught. - Docstring notes the cache peek is CLI/TUI best-effort.
All 54 credits tests pass on the new head. LGTM.
It currently causes confusion when a free or paid-with-no-credits user goes to use a free model