feat(meta-ai): live-first model catalog + generic contributor warning
- Register meta-ai as a live-first picker provider so the /v1/models catalog leads the picker; new models appear without a PR - Override fetch_models to exclude non-chat models (muse-image-*, muse-voice-*) from the picker; new chat model families pass through automatically - Slim fallback_models to a single safety-net entry (muse-spark-1.2), shown only when the live fetch fails - Make data-policy contributor warning model-generic (not hardcoded to 1.2) so it covers any future -contributor model - Update test assertion to match generic warning text LOCAL ONLY — pre-launch, not for push.
This commit is contained in:
@@ -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."
|
||||
|
||||
@@ -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"}
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user