Skip to content

Commit 9c16b5e

Browse files
committed
feat(minimax): add MiniMax provider with tier-aware rate limiting
Add MiniMax as a built-in provider using the generic tier framework (#82). MiniMax is an OpenAI-compatible API provider with the M2.x model family (M2.7, M2.5, M2.1, M2) and published token plan rate tiers. Changes: - New MiniMaxProvider with RATE_LIMIT_TIERS (starter/plus/max/ultra) derived from published 5-hour rolling window limits - Uses resolve_rate_limiter() from BaseProvider for tier resolution - reasoning_split=True by default to separate thinking from content - Bumped retry budget: 5 retries / 30s max for load-shedding tolerance - Registered in provider registry with openai package dependency hint - Conservative PROVIDER_DEFAULTS (Starter-tier: 5 RPM / 25K TPM) - CLI env vars: MINIMAX_API_KEY, MINIMAX_BASE_URL, MINIMAX_REASONING_SPLIT, MINIMAX_TIER - 30 unit tests (constructor, tiers, generate, stream_chat, registry) Rate limit tiers (from https://platform.minimax.io/docs/token-plan/intro): Starter: 1,500 req/5hrs -> 5 RPM / 25K TPM Plus: 4,500 req/5hrs -> 15 RPM / 75K TPM Max: 15,000 req/5hrs -> 50 RPM / 250K TPM Ultra: 30,000 req/5hrs -> 100 RPM / 500K TPM Highspeed variants (e.g., MiniMax-M2.7-highspeed) share the same rate limits as their base plan -- the difference is faster inference, not quota. This provider is structurally identical to Z.AI (#83) and was trivial to implement because both use the generic tier framework. The framework eliminated all per-provider boilerplate for tier resolution. Depends on: #82 (generic tier framework) Ref: #68
1 parent ed682fb commit 9c16b5e

5 files changed

Lines changed: 802 additions & 1 deletion

File tree

packages/cli/src/repowise/cli/helpers.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,16 @@ def resolve_provider(
278278
kwargs["base_url"] = os.environ["ZAI_BASE_URL"]
279279
if os.environ.get("ZAI_THINKING"):
280280
kwargs["thinking"] = os.environ["ZAI_THINKING"]
281+
elif provider_name == "minimax":
282+
# MiniMax: API key, base URL, reasoning_split, and tier
283+
if os.environ.get("MINIMAX_API_KEY"):
284+
kwargs["api_key"] = os.environ["MINIMAX_API_KEY"]
285+
if os.environ.get("MINIMAX_BASE_URL"):
286+
kwargs["base_url"] = os.environ["MINIMAX_BASE_URL"]
287+
if os.environ.get("MINIMAX_REASONING_SPLIT"):
288+
kwargs["reasoning_split"] = os.environ["MINIMAX_REASONING_SPLIT"].lower() == "true"
289+
if os.environ.get("MINIMAX_TIER"):
290+
kwargs["tier"] = os.environ["MINIMAX_TIER"]
281291

282292
return get_provider(provider_name, **kwargs)
283293

@@ -336,11 +346,23 @@ def resolve_provider(
336346
if os.environ.get("ZAI_THINKING"):
337347
kwargs["thinking"] = os.environ["ZAI_THINKING"]
338348
return get_provider("zai", **kwargs)
349+
# MiniMax: check for API key
350+
if os.environ.get("MINIMAX_API_KEY") and os.environ["MINIMAX_API_KEY"].strip():
351+
kwargs = {"api_key": os.environ["MINIMAX_API_KEY"]}
352+
if model:
353+
kwargs["model"] = model
354+
if os.environ.get("MINIMAX_BASE_URL"):
355+
kwargs["base_url"] = os.environ["MINIMAX_BASE_URL"]
356+
if os.environ.get("MINIMAX_REASONING_SPLIT"):
357+
kwargs["reasoning_split"] = os.environ["MINIMAX_REASONING_SPLIT"].lower() == "true"
358+
if os.environ.get("MINIMAX_TIER"):
359+
kwargs["tier"] = os.environ["MINIMAX_TIER"]
360+
return get_provider("minimax", **kwargs)
339361

340362
raise click.ClickException(
341363
"No provider configured. Use --provider, set REPOWISE_PROVIDER, "
342364
"or set ANTHROPIC_API_KEY / OPENAI_API_KEY / OLLAMA_BASE_URL / GEMINI_API_KEY / "
343-
"LITELLM_API_KEY / LITELLM_BASE_URL / ZAI_API_KEY."
365+
"LITELLM_API_KEY / LITELLM_BASE_URL / ZAI_API_KEY / MINIMAX_API_KEY."
344366
)
345367

346368

@@ -381,6 +403,7 @@ def _is_env_var_exists(var_name: str) -> bool:
381403
"LITELLM_BASE_URL",
382404
], # Either one (API key for cloud, base URL for local)
383405
"zai": ["ZAI_API_KEY"],
406+
"minimax": ["MINIMAX_API_KEY"],
384407
}
385408

386409
if provider_name:

0 commit comments

Comments
 (0)