This commit is contained in:
Julian Sam 2026-11-07 00:43:42 +03:00 • committed by GitHub
commit 8abd4c480e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 8 deletions

View file

@ -73,7 +73,6 @@ from litellm.types.utils import (
ModelResponse,
ModelResponseStream,
)
from litellm.utils import supports_reasoning
if TYPE_CHECKING:
from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj
@ -96,16 +95,15 @@ def _model_uses_max_completion_tokens(model: str) -> bool:
and accept ``maxCompletionTokens`` everywhere, so route the whole vendor
prefix to it rather than chasing each new release in
``model_prices_and_context_window.json``. The ``openai.gpt-oss-*`` open
weights are served by OCI's own stack and keep ``maxTokens``. Any other
vendor falls back to the catalog's ``supports_reasoning`` flag.
weights are served by OCI's own stack and keep ``maxTokens``, as does every
other vendor whatever its catalog reasoning flag: OCI's Gemini models ignore
``maxCompletionTokens`` and fall back to a default of about 4K output tokens.
"""
if not model:
return False
name: Final = model[4:] if model.lower().startswith("oci/") else model
lowered: Final = name.lower()
if lowered.startswith("openai."):
return not lowered.startswith("openai.gpt-oss")
return supports_reasoning(model=name, custom_llm_provider="oci")
return lowered.startswith("openai.") and not lowered.startswith("openai.gpt-oss")
def _iter_sse_events(stream: Iterator[str]) -> Iterator[str]:
@ -572,8 +570,7 @@ class OCIChatConfig(BaseConfig):
# OpenAI reasoning models on OCI (e.g. GPT-5 family) reject "maxTokens"
# and require "maxCompletionTokens" per OCI's /20231130/Chat schema.
# Driven by the supports_reasoning flag in the model catalog. Cohere's
# endpoint uses "maxTokens" regardless, so the override is GENERIC-only.
# Cohere's endpoint uses "maxTokens" regardless, so the override is GENERIC-only.
max_tokens_key: Final = (
"maxCompletionTokens"
if vendor != OCIVendors.COHERE and model and _model_uses_max_completion_tokens(model)

View file

@ -8,6 +8,7 @@ from unittest.mock import MagicMock
import httpx
from litellm import ModelResponse
from litellm.constants import DEFAULT_OCI_CHAT_MAX_TOKENS
from litellm.llms.oci.chat.generic import (
adapt_messages_to_generic_oci_standard,
adapt_messages_to_generic_oci_standard_content_message,
@ -369,6 +370,27 @@ def _register_oci_gpt5_in_catalog():
litellm.model_cost.pop(key, None)
@pytest.fixture
def _flag_oci_gemini_as_reasoning_in_catalog():
"""Mark OCI's Gemini models as reasoning models, as the bundled catalog has done since #41902,
whichever map ``litellm.model_cost`` was populated from."""
import litellm
keys = ("oci/google.gemini-2.5-pro", "oci/google.gemini-2.5-flash")
originals = {key: litellm.model_cost.get(key) for key in keys}
for key in keys:
litellm.model_cost[key] = {
**(originals[key] or {"litellm_provider": "oci", "mode": "chat"}),
"supports_reasoning": True,
}
yield
for key, original in originals.items():
if original is None:
litellm.model_cost.pop(key, None)
else:
litellm.model_cost[key] = original
class TestGpt5MaxCompletionTokens:
def test_helper_detects_gpt5_family(self, _register_oci_gpt5_in_catalog):
assert _model_uses_max_completion_tokens("openai.gpt-5") is True
@ -441,6 +463,18 @@ class TestGpt5MaxCompletionTokens:
assert out.get("maxTokens") == 64
assert "maxCompletionTokens" not in out
@pytest.mark.parametrize("model", ["google.gemini-2.5-pro", "oci/google.gemini-2.5-flash"])
@pytest.mark.parametrize(("params", "expected"), [({"max_tokens": 64}, 64), ({}, DEFAULT_OCI_CHAT_MAX_TOKENS)])
def test_gemini_reasoning_models_keep_max_tokens(
self, model, params, expected, _flag_oci_gemini_as_reasoning_in_catalog
):
"""Regression: OCI's Gemini models ignore maxCompletionTokens and fall back to a default of
about 4K output tokens (verified against live OCI on 2026-09-28), so a reasoning flag in the
catalog must not move the limit off maxTokens."""
out = OCIChatConfig()._get_optional_params(OCIVendors.GENERIC, params, model=model)
assert out.get("maxTokens") == expected
assert "maxCompletionTokens" not in out
def test_cohere_reasoning_model_keeps_max_tokens(self):
cfg = OCIChatConfig()
out = cfg._get_optional_params(