fix(provider): handle hosted Kimi reasoning protocols

This commit is contained in:
fdc310
2026-08-06 00:20:00 +08:00
parent 098a15bd14
commit 1f415459d9
2 changed files with 56 additions and 1 deletions
@@ -164,6 +164,12 @@ class LiteLLMRequester(requester.ProviderAPIRequester):
_EMBEDDING_MODEL_HINTS = ('embedding', 'embed', 'bge-', 'e5-', 'm3e', 'gte-', 'text-embedding')
_RERANK_MODEL_HINTS = ('rerank', 're-rank', 're_rank')
_QWEN_DEDICATED_THINKING_MODELS = frozenset(
{
'qwen3.7-max-preview',
'qwen3.7-max-2026-05-17',
}
)
_INFERRED_EFFORT_PROVIDERS = frozenset(
{
'anthropic',
@@ -392,6 +398,14 @@ class LiteLLMRequester(requester.ProviderAPIRequester):
return inferred_family
return 'volcengine' if requester_name == 'volcark-chat-completions' else ''
# Bailian's compatible endpoint also hosts Kimi models. Keep those
# models on Kimi's ``thinking`` protocol instead of Qwen's
# ``enable_thinking`` protocol.
if requester_name == 'bailian-chat-completions':
inferred_family = self._infer_reasoning_family_from_model_name(model_name)
if inferred_family == 'kimi':
return inferred_family
requester_family = self._REQUESTER_REASONING_FAMILIES.get(requester_name)
if requester_family:
return requester_family
@@ -428,7 +442,11 @@ class LiteLLMRequester(requester.ProviderAPIRequester):
@staticmethod
def _is_dedicated_qwen_thinking_model(model_name: str) -> bool:
normalized_name = model_name.lower().rsplit('/', 1)[-1]
return normalized_name.startswith('qwq') or '-thinking' in normalized_name
return (
normalized_name in LiteLLMRequester._QWEN_DEDICATED_THINKING_MODELS
or normalized_name.startswith('qwq')
or '-thinking' in normalized_name
)
def _known_reasoning_levels(self, model_name: str, family: str) -> list[str] | None:
normalized_name = model_name.lower().rsplit('/', 1)[-1]
@@ -237,6 +237,43 @@ def test_qwen_mixed_and_dedicated_thinking_profiles(monkeypatch):
assert dedicated['levels'] == ['provider_default']
@pytest.mark.parametrize('model_name', ['qwen3.7-max-preview', 'qwen3.7-max-2026-05-17'])
def test_qwen_dedicated_thinking_release_models_are_not_toggleable(model_name, monkeypatch):
request = _requester('openai', 'bailian-chat-completions')
monkeypatch.setattr(request, '_supports_reasoning', lambda _: False)
capabilities = request.get_reasoning_capabilities(_runtime_model(request, name=model_name, abilities=[]))
assert capabilities['levels'] == ['provider_default']
@pytest.mark.parametrize(
('model_name', 'expected_levels'),
[
('kimi-k2.6', ['provider_default', 'disabled', 'enabled']),
('kimi-k2.5', ['provider_default', 'disabled', 'enabled']),
('kimi-k2.7-code', ['provider_default']),
('kimi-k2-thinking', ['provider_default']),
],
)
def test_bailian_kimi_profiles_use_kimi_model_rules(model_name, expected_levels, monkeypatch):
request = _requester('openai', 'bailian-chat-completions')
monkeypatch.setattr(request, '_supports_reasoning', lambda _: False)
capabilities = request.get_reasoning_capabilities(_runtime_model(request, name=model_name, abilities=[]))
assert capabilities['levels'] == expected_levels
def test_bailian_kimi_uses_thinking_protocol_instead_of_qwen_protocol(monkeypatch):
request = _requester('openai', 'bailian-chat-completions')
monkeypatch.setattr(request, '_supports_reasoning', lambda _: False)
assert request._build_reasoning_args(_runtime_model(request, 'disabled', name='kimi-k2.6')) == {
'extra_body': {'thinking': {'type': 'disabled'}}
}
def test_doubao_exposes_documented_effort_range(monkeypatch):
request = _requester('openai', 'doubao-chat-completions')
monkeypatch.setattr(request, '_supports_reasoning', lambda _: False)