diff --git a/__init__.py b/__init__.py index 143a0af..c087567 100644 --- a/__init__.py +++ b/__init__.py @@ -98,7 +98,11 @@ def register(ctx) -> None: class MuseCodeSubscriptionProfile(ProviderProfile): """Meta Model API via the Muse Code subscription.""" - _NON_CHAT_PREFIXES = ("muse-image-", "muse-voice-") + # Allowlist: this provider serves the Muse Spark chat family. The live + # endpoint also returns other families (sam-*, muse-image-*, + # muse-voice-*) that are not usable as chat models — a denylist + # would leak the next such family, so only muse-spark-* is admitted. + _CHAT_FAMILY_PREFIX = "muse-spark-" def fetch_models( self, @@ -112,11 +116,7 @@ def fetch_models( ) if live is None: return None - return [ - m - for m in live - if not any(m.startswith(p) for p in self._NON_CHAT_PREFIXES) - ] + return [m for m in live if m.startswith(self._CHAT_FAMILY_PREFIX)] def build_api_kwargs_extras( self, diff --git a/plugin.yaml b/plugin.yaml index 507082f..11f8e8b 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,6 +1,6 @@ name: muse-code-subscription kind: model-provider -version: 0.2.1 +version: 0.2.2 description: Muse Spark in Hermes billed to the Muse Code monthly login (device-code login, no API key) author: TheStreamCode license: MIT @@ -8,3 +8,4 @@ homepage: https://github.com/TheStreamCode/hermes-muse-code tags: [meta, muse-spark, subscription] requires_hermes: ">=0.21.3" + diff --git a/tests/test_muse_code_provider.py b/tests/test_muse_code_provider.py index 98d002d..6d1cc86 100644 --- a/tests/test_muse_code_provider.py +++ b/tests/test_muse_code_provider.py @@ -177,15 +177,24 @@ def test_reasoning_effort_mapping(tmp_path, monkeypatch): ) -def test_fetch_models_filters_non_chat(tmp_path, monkeypatch): +def test_fetch_models_admits_only_muse_spark(tmp_path, monkeypatch): monkeypatch.setenv("MUSE_CODE_SUB_CREDENTIALS", str(tmp_path / "c.json")) _, registered = _load_plugin() profile = registered["muse-code"] - live = ["muse-spark-1.3", "muse-image-1.0", "muse-voice-transcribe-1.0"] + live = [ + "muse-spark-1.3", + "muse-spark-1.2-contributor", + "sam-3.1", + "muse-image-1.0", + "muse-voice-transcribe-1.0", + ] with patch.object( type(profile).__mro__[1], "fetch_models", return_value=live ): - assert profile.fetch_models(api_key="k") == ["muse-spark-1.3"] + assert profile.fetch_models(api_key="k") == [ + "muse-spark-1.3", + "muse-spark-1.2-contributor", + ] with patch.object( type(profile).__mro__[1], "fetch_models", return_value=None ):