From dfe481121e935acad901a4f90334171699a25d74 Mon Sep 17 00:00:00 2001 From: octo-patch <266937838+octo-patch@users.noreply.github.com> Date: Wed, 29 Jul 2026 15:03:13 +0000 Subject: [PATCH 1/2] feat(providers): seed direct MiniMax default model and shortlist --- raven/providers/common_models.py | 4 ++++ raven/providers/registry.py | 1 + tests/test_provider_catalog.py | 1 + 3 files changed, 6 insertions(+) diff --git a/raven/providers/common_models.py b/raven/providers/common_models.py index ee32cf89..818d7640 100644 --- a/raven/providers/common_models.py +++ b/raven/providers/common_models.py @@ -75,6 +75,10 @@ "deepseek/deepseek-v4-flash", "deepseek/deepseek-v4-pro", ], + "minimax": [ + "minimax/MiniMax-M3", + "minimax/MiniMax-M2.7", + ], "minimax_global": [ "minimax-global/MiniMax-M3", "minimax-global/MiniMax-M2.7", diff --git a/raven/providers/registry.py b/raven/providers/registry.py index 6a4f0ff7..809baacd 100644 --- a/raven/providers/registry.py +++ b/raven/providers/registry.py @@ -357,6 +357,7 @@ def label(self) -> str: default_api_base="https://api.minimax.io/v1", strip_model_prefix=False, model_overrides=(), + default_model="minimax/MiniMax-M3", ), ProviderSpec( name="minimax_global", diff --git a/tests/test_provider_catalog.py b/tests/test_provider_catalog.py index 132c2048..7d4df69f 100644 --- a/tests/test_provider_catalog.py +++ b/tests/test_provider_catalog.py @@ -64,6 +64,7 @@ def test_provider_names_are_unique() -> None: "zhipu", "dashscope", "groq", + "minimax", "minimax_global", "minimax_cn", ] From 6425c3aa15a0a9e400c2024f9af340a16e8629dc Mon Sep 17 00:00:00 2001 From: octo-patch <266937838+octo-patch@users.noreply.github.com> Date: Tue, 11 Aug 2026 19:13:18 +0800 Subject: [PATCH 2/2] fix(providers): pin current MiniMax context windows --- raven/providers/rates.py | 26 ++++++++++++++++++++++++-- raven/providers/registry.py | 5 +++++ tests/test_provider_rates.py | 13 +++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/raven/providers/rates.py b/raven/providers/rates.py index e00365cb..01de7304 100644 --- a/raven/providers/rates.py +++ b/raven/providers/rates.py @@ -527,11 +527,29 @@ def _try_litellm_context_window(model: str, *, allow_import: bool = True) -> int return None +def _registry_context_window(model: str) -> int | None: + """A current vendor window declared by the provider registry, or None.""" + from raven.providers.registry import find_by_model, find_by_name, split_model_id + + prefix, vendor_model = split_model_id(model) + if not prefix: + return None + spec = find_by_model(model) + if spec is None: + return None + source = find_by_name(spec.metadata_prefix) if spec.metadata_prefix else spec + if source is None: + return None + wanted = vendor_model.casefold() + return next((window for model_id, window in source.model_context_windows if model_id.casefold() == wanted), None) + + def resolve_context_window(model: str, *, allow_fetch: bool = True) -> int | None: """Return a model's real context window in tokens, or None. - LiteLLM's static metadata first, then OpenRouter's catalogue for ids that - name OpenRouter. The snapshot is deliberately not a source: a window sizes + Current model facts declared by the routing registry come first, then + LiteLLM's static metadata, then OpenRouter's catalogue for ids that name + OpenRouter. The snapshot is deliberately not a source: a window sizes trimming, so a community-maintained file that goes stale or wrong would shape the next request rather than cost a label. Unknown models return None so the caller keeps its configured default. @@ -542,6 +560,10 @@ def resolve_context_window(model: str, *, allow_fetch: bool = True) -> int | Non behalf (see ``_try_litellm_context_window``) -- a caller cheap enough to pass this is cheap enough not to pay a fresh import either. """ + window = _registry_context_window(model) + if window: + return window + window = _try_litellm_context_window(model, allow_import=allow_fetch) if window: return window diff --git a/raven/providers/registry.py b/raven/providers/registry.py index 7c9d0256..d6529c7d 100644 --- a/raven/providers/registry.py +++ b/raven/providers/registry.py @@ -80,6 +80,10 @@ class ProviderSpec: # per-model param overrides, e.g. (("kimi-k2.5", {"temperature": 1.0}),) model_overrides: tuple[tuple[str, dict[str, Any]], ...] = () + # Vendor model id to context window for current models the pinned LiteLLM + # metadata does not yet describe correctly. + model_context_windows: tuple[tuple[str, int], ...] = () + # OAuth-based providers (e.g., OpenAI Codex) don't use API keys is_oauth: bool = False # if True, uses OAuth flow instead of API key @@ -484,6 +488,7 @@ def claims(self, model: str) -> bool: detect_by_base_keyword="", strip_model_prefix=False, model_overrides=(), + model_context_windows=(("MiniMax-M3", 1_000_000), ("MiniMax-M2.7", 204_800)), # Needed by `provider test` and the wizard preflight, which probe # /v1/models before any LiteLLM call resolves an endpoint. default_api_base="https://api.minimax.io/v1", diff --git a/tests/test_provider_rates.py b/tests/test_provider_rates.py index a88e558c..65d061dd 100644 --- a/tests/test_provider_rates.py +++ b/tests/test_provider_rates.py @@ -263,6 +263,19 @@ def test_a_litellm_mapped_window_comes_from_litellm_with_no_network(monkeypatch) assert counter["calls"] == 0 +@pytest.mark.parametrize( + ("model", "expected"), + [ + ("minimax/MiniMax-M3", 1_000_000), + ("minimax/MiniMax-M2.7", 204_800), + ("minimax-global/MiniMax-M3", 1_000_000), + ("minimax-cn/MiniMax-M2.7", 204_800), + ], +) +def test_minimax_current_windows_come_from_the_provider_registry(model: str, expected: int) -> None: + assert resolve_context_window(model, allow_fetch=False) == expected + + def test_an_openrouter_window_falls_back_to_the_live_table(monkeypatch): _patch_litellm_info(monkeypatch, _litellm_miss) _patch_openrouter(monkeypatch, lambda req: _models_response(_DEEPSEEK_MODELS))