Ollama Cloud model IDs with :cloud/-cloud suffix handling
Cluster 16179 · hermes cli. Data as of
Nothing open on GitHub. Fix merged in #19881 on 4 May 2026. Check it covers your case.
The short answer
- Known?
- Yes. 4 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #19881. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
unresolved. That is separate from the fix event. - Still open
- Nothing open on GitHub.
The members appear to share one theme: Ollama Cloud model IDs carrying a :cloud or -cloud suffix (e.g. kimi-k2.6:cloud), reported in one bug issue as producing wrong names and 400/404 errors. The other members are pull requests that propose stripping or sanitizing that suffix, including two with identical titles.
Open issues0
Open PRs0
Fixes on record
-
#19881 fix(models): strip :cloud/-cloud suffix from models.dev Ollama Cloud IDs
files:
hermes_cli/models.py,tests/hermes_cli/test_ollama_cloud_provider.pyShow the diff
-
hermes_cli/models.py@@ -2906,6 +2906,19 @@ def fetch_api_models( _OLLAMA_CLOUD_CACHE_TTL = 3600 # 1 hour +def _strip_ollama_cloud_suffix(model_id: str) -> str: + """Strip :cloud / -cloud suffixes that models.dev appends to Ollama Cloud IDs. + + The live API uses clean IDs (e.g. 'kimi-k2.6') while models.dev sometimes + returns them as 'kimi-k2.6:cloud'. Normalising before the dedup merge + prevents duplicate entries in the merged model list. + """ + for suffix in (":cloud", "-cloud"): + if model_id.endswith(suffix): + return model_id[: -len(suffix)] + return model_id + + def _ollama_cloud_cache_path() -> Path: """Return the path for the Ollama Cloud model cache.""" from hermes_constants import get_hermes_home @@ -3001,9 +3014,10 @@ def fetch_ollama_cloud_models( seen.add(m) merged.append(m) for m in mdev_models: - if m and m not in seen: - seen.add(m) - merged.append(m) + normalized = _strip_ollama_cloud_suffix(m) + if normalized and normalized not in seen: + seen.add(normalized) + merged.append(normalized) if merged: _save_ollama_cloud_cache(merged) return merged -
tests/hermes_cli/test_ollama_cloud_provider.py@@ -401,6 +401,103 @@ def test_get_provider(self): assert pdef.transport == "openai_chat" +# ── Cloud Suffix Stripping ── + +class TestOllamaCloudSuffixStripping: + """models.dev appends :cloud / -cloud suffixes that the live API omits. + + fetch_ollama_cloud_models() must normalise these before the dedup merge so + users never see broken IDs like 'kimi-k2.6:cloud' in the model picker. + """ + + def test_strips_colon_cloud_suffix(self, tmp_path, monkeypatch): + """:cloud suffix from models.dev is stripped before merge.""" + from hermes_cli.models import fetch_ollama_cloud_models + + monkeypatch.setenv("HERMES_HOME", str(tmp_path)) + monkeypatch.delenv("OLLAMA_API_KEY", raising=False) + + mock_mdev = { + "ollama-cloud": { + "models": {"kimi-k2.6:cloud": {"tool_call": True}} + } + } + with patch("agent.models_dev.fetch_models_dev", return_value=mock_mdev): + result = fetch_ollama_cloud_models(force_refresh=True) + + assert "kimi-k2.6" in result + assert "kimi-k2.6:cloud" not in result + + def test_strips_dash_cloud_suffix(self, tmp_path, monkeypatch): + """-cloud suffix from models.dev is stripped before merge.""" + from hermes_cli.models import fetch_ollama_cloud_models + + monkeypatch.setenv("HERMES_HOME", str(tmp_path)) + monkeypatch.delenv("OLLAMA_API_KEY", raising=False) + + mock_mdev = { + "ollama-cloud": { + "models": {"qwen3-coder:480b-cloud": {"tool_call": True}} + } + } + with patch("agent.models_dev.fetch_models_dev", return_value=mock_mdev): + result = fetch_ollama_cloud_models(force_refresh=True) + + assert "qwen3-coder:480b" in result + assert "qwen3-coder:480b-cloud" not in result + + def test_no_duplicate_when_live_clean_and_mdev_suffixed(self, tmp_path, monkeypatch): + """Live API returns clean ID; mdev has :cloud variant — result has exactly one entry.""" + from hermes_cli.models import fetch_ollama_cloud_models + + monkeypatch.setenv("HERMES_HOME", str(tmp_path)) + monkeypatch.setenv("OLLAMA_API_KEY", "test-key") + + mock_mdev = { + "ollama-cloud": { + "models": { + "kimi-k2.6:cloud": {"tool_call": True}, + "glm-5.1:cloud": {"tool_call": True}, + } + } + } + with patch("hermes_cli.models.fetch_api_models", return_value=["kimi-k2.6", "glm-5.1"]), \ + patch("agent.models_dev.fetch_models_dev", return_value=mock_mdev): + result = fetch_ollama_cloud_models(force_refresh=True) + + assert result.count("kimi-k2.6") == 1 + assert result.count("glm-5.1") == 1 + assert "kimi-k2.6:cloud" not in result + assert "glm-5.1:cloud" not in result + + def test_unsuffixed_model_id_unchanged(self, tmp_path, monkeypatch): + """Model IDs without :cloud / -cloud suffix are passed through unchanged.""" + from hermes_cli.models import fetch_ollama_cloud_models + + monkeypatch.setenv("HERMES_HOME", str(tmp_path)) + monkeypatch.delenv("OLLAMA_API_KEY", raising=False) + + mock_mdev = { + "ollama-cloud": { + "models": {"nemotron-3-nano:30b": {"tool_call": True}} + } + } + with patch("agent.models_dev.fetch_models_dev", return_value=mock_mdev): + result = fetch_ollama_cloud_models(force_refresh=True) + + assert "nemotron-3-nano:30b" in result + + def test_strip_suffix_helper(self): + """Unit test for the _strip_ollama_cloud_suffix helper.""" + from hermes_cli.models import _strip_ollama_cloud_suffix + + assert _strip_ollama_cloud_suffix("kimi-k2.6:cloud") == "kimi-k2.6" + assert _strip_ollama_cloud_suffix("glm-5.1:cloud") == "glm-5.1" + assert _strip_ollama_cloud_suffix("qwen3-coder:480b-cloud") == "qwen3-coder:480b" + assert _strip_ollama_cloud_suffix("nemotron-3-nano:30b") == "nemotron-3-nano:30b" + assert _strip_ollama_cloud_suffix("") == "" + + # ── Auxiliary Model ── class TestOllamaCloudAuxiliary:
-
2 PRs closed without merging
From the close comments: merged via another change 1 · superseded by another PR 1
Closed issues · 1
- Closed#16179[Bug]: Ollama Cloud model list shows wrong names with :cloud / -cloud suffix (e.g. kimi-k2.6:cloud), causing 400/404
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.50: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- hermes cli
- Merged PRs
- #19881
- Closed issues
- 1
- Attempts
- 2 PRs closed without merging
- Fix link checked
- 4 May 2026