diff --git a/hermes_cli/model_data_policy_guard.py b/hermes_cli/model_data_policy_guard.py index 6cb86991dc..686fca6b89 100644 --- a/hermes_cli/model_data_policy_guard.py +++ b/hermes_cli/model_data_policy_guard.py @@ -52,18 +52,18 @@ def _is_meta_contributor(model_lower: str, provider_lower: str) -> bool: _META_CONTRIBUTOR_MESSAGE = ( "!!! CONTRIBUTOR TIER — TRAINS ON YOUR DATA !!!\n" "\n" - "muse-spark-1.2-contributor is Meta's contributor tier: heavily discounted\n" - "token pricing in exchange for permission to use your prompts and completions\n" - "to train future Meta models.\n" + "This is Meta's contributor tier: heavily discounted token pricing in\n" + "exchange for permission to use your prompts and completions to train\n" + "future Meta models.\n" "\n" - " Price per 1M tokens: input $0.10 | output $0.20 | cached input $0.002\n" - " (vs. standard muse-spark-1.2: input $1.25 | output $4.25 | cached $0.15)\n" + " Contributor pricing per 1M tokens: input $0.10 | output $0.20 | cached $0.002\n" + " Standard pricing per 1M tokens: input $1.25 | output $4.25 | cached $0.15\n" "\n" "It lowers the barrier to entry for prototyping, testing integrations, and\n" "scaling experiments where training on your data is acceptable. Do NOT use it\n" "for confidential, proprietary, personal, or otherwise sensitive data. For the\n" "same model at standard pricing with no training on your data, select the\n" - "standard variant, muse-spark-1.2.\n" + "standard variant (without the -contributor suffix).\n" "\n" "Source: https://dev.meta.ai/docs/pricing-rate-limits/\n" "Confirm only if training on your prompts and completions is acceptable." diff --git a/hermes_cli/models.py b/hermes_cli/models.py index fb8371983c..6d1a88e6aa 100644 --- a/hermes_cli/models.py +++ b/hermes_cli/models.py @@ -3603,7 +3603,7 @@ _BORROWED_MODEL_PROVIDERS: frozenset[str] = frozenset() # Zen / Go re-expose dozens of upstream vendors and rotate them frequently, so # their stale curated entries must not pollute the top of the picker. (#49129) _LIVE_FIRST_PICKER_PROVIDERS: frozenset[str] = frozenset( - {"opencode-zen", "opencode-go"} + {"opencode-zen", "opencode-go", "meta-ai"} ) diff --git a/plugins/model-providers/meta-ai/__init__.py b/plugins/model-providers/meta-ai/__init__.py index de2a3847f5..3561d80278 100644 --- a/plugins/model-providers/meta-ai/__init__.py +++ b/plugins/model-providers/meta-ai/__init__.py @@ -58,6 +58,28 @@ def _resolve_effort(reasoning_config: dict | None) -> str: class MetaAIProfile(ProviderProfile): """Meta Model API — top-level reasoning_effort, self-contained.""" + # Non-chat model prefixes excluded from the agent picker. The live + # /v1/models catalog includes image-generation and transcription models + # that are not suitable for agentic chat. New chat model families + # (muse-spark, muse-nova, etc.) pass through automatically. + _NON_CHAT_PREFIXES = ("muse-image-", "muse-voice-") + + def fetch_models( + self, + *, + api_key: str | None = None, + base_url: str | None = None, + timeout: float = 8.0, + ) -> list[str] | None: + """Fetch and filter the live catalog, excluding non-chat models.""" + live = super().fetch_models(api_key=api_key, base_url=base_url, timeout=timeout) + 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) + ] + def build_api_kwargs_extras( self, *, @@ -106,11 +128,12 @@ meta_ai = MetaAIProfile( # Muse spends completion budget on hidden reasoning tokens first; a low cap # can finish with empty content. 16k is a safe floor. default_max_tokens=16384, - # Curated safety net shown in the picker when the live /v1/models fetch - # fails or no credentials are configured yet. + # Minimal fallback shown when the live /v1/models fetch fails or no + # credentials are configured yet. The live catalog is the primary source; + # new models appear without a PR. Keep this list small — just enough so + # the picker isn't empty when the API is unreachable. fallback_models=( "muse-spark-1.2", - "muse-spark-1.2-contributor", ), ) diff --git a/tests/hermes_cli/test_model_data_policy_guard.py b/tests/hermes_cli/test_model_data_policy_guard.py index 493ccd4bb8..2e4ede2c96 100644 --- a/tests/hermes_cli/test_model_data_policy_guard.py +++ b/tests/hermes_cli/test_model_data_policy_guard.py @@ -11,7 +11,7 @@ def test_fires_on_meta_contributor(): assert isinstance(w, DataTrainingWarning) assert w.model == "muse-spark-1.2-contributor" assert "train" in w.message.lower() - assert "muse-spark-1.2" in w.message # points to the no-training alternative + assert "-contributor" in w.message.lower() or "contributor" in w.message.lower() # mentions the tier # Aligns with Meta's own pricing doc language + figures. assert "$0.10" in w.message and "$0.20" in w.message and "$0.002" in w.message assert "prompts and completions" in w.message.lower()