From 77aa026ca67f65a8e781df1b82c0786d511bfd21 Mon Sep 17 00:00:00 2001 From: githubespresso407 Date: Sat, 18 Jul 2026 15:09:43 -0500 Subject: [PATCH] Resolve kimi-k3 context length to 1M on canonical Kimi Coding endpoints Kimi Coding serves K3 under the bare slug 'k3', but users can also configure or select the public-facing aliases 'kimi-k3' and 'kimi-k3-cot'. The endpoint-scoped 1M context window was only keyed on the bare 'k3' slug, so selecting 'kimi-k3' fell through to the generic 'kimi' catch-all (262k). Extend the guard in _endpoint_scoped_context_length to also recognize 'kimi-k3' and 'kimi-k3-cot', while keeping the endpoint check that limits the 1M value to https://api.kimi.com/coding (legacy Moonshot endpoints still fall back to 262k). Update the existing test to cover all three aliases. Fixes: context window limited to 262k when using kimi-k3 via kimi-coding. --- agent/model_metadata.py | 10 ++++++++-- tests/agent/test_model_metadata.py | 14 ++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/agent/model_metadata.py b/agent/model_metadata.py index 50e78a8868fd..821a7ebe01c1 100644 --- a/agent/model_metadata.py +++ b/agent/model_metadata.py @@ -543,7 +543,13 @@ def _is_known_provider_base_url(base_url: str) -> bool: def _endpoint_scoped_context_length(model: str, base_url: str) -> Optional[int]: - """Return metadata confirmed only for one provider endpoint.""" + """Return metadata confirmed only for the Kimi Coding endpoint. + + Kimi Coding serves K3 under the bare slug ``k3``, but users may also + configure or select the public-facing aliases ``kimi-k3`` and + ``kimi-k3-cot``. Only canonical ``https://api.kimi.com/coding`` endpoints + (legacy Moonshot keys do not serve K3) get the 1 Mi context window. + """ normalized = _normalize_base_url(base_url) try: parsed = urlparse(normalized) @@ -559,7 +565,7 @@ def _endpoint_scoped_context_length(model: str, base_url: str) -> Optional[int]: and parsed.path.rstrip("/") in {"/coding", "/coding/v1"} and not parsed.query and not parsed.fragment - and model.strip().lower() == "k3" + and model.strip().lower() in {"k3", "kimi-k3", "kimi-k3-cot"} ): return 1_048_576 return None diff --git a/tests/agent/test_model_metadata.py b/tests/agent/test_model_metadata.py index 166e0c1f97fa..ddd49834d579 100644 --- a/tests/agent/test_model_metadata.py +++ b/tests/agent/test_model_metadata.py @@ -199,14 +199,16 @@ class TestDefaultContextLengths: ) for base_url in accepted_urls: - assert get_model_context_length( - "k3", provider="kimi-coding", base_url=base_url - ) == 1_048_576 + for model in ("k3", "kimi-k3", "kimi-k3-cot"): + assert get_model_context_length( + model, provider="kimi-coding", base_url=base_url + ) == 1_048_576 for base_url in rejected_urls: - assert get_model_context_length( - "k3", provider="kimi-coding", base_url=base_url - ) != 1_048_576 + for model in ("k3", "kimi-k3", "kimi-k3-cot"): + assert get_model_context_length( + model, provider="kimi-coding", base_url=base_url + ) != 1_048_576 def test_grok_substring_matching(self): # Longest-first substring matching must resolve the real xAI model