Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions raven/providers/common_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,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",
Expand Down
26 changes: 24 additions & 2 deletions raven/providers/rates.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
6 changes: 6 additions & 0 deletions raven/providers/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -484,9 +488,11 @@ 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",
default_model="minimax/MiniMax-M3",
),
ProviderSpec(
name="minimax_global",
Expand Down
1 change: 1 addition & 0 deletions tests/test_provider_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def test_registry_and_schema_declare_the_same_providers() -> None:
"zai",
"dashscope",
"groq",
"minimax",
"minimax_global",
"minimax_cn",
]
Expand Down
13 changes: 13 additions & 0 deletions tests/test_provider_rates.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down