mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-06-15 15:24:06 +00:00
fix(providers): use max_completion_tokens for gpt-5/o-series on flagless specs (#4261)
This commit is contained in:
parent
fd9fc38f41
commit
a779e7c29e
@ -93,6 +93,14 @@ def _model_slug(model_name: str) -> str:
|
|||||||
return model_name.lower().rsplit("/", 1)[-1]
|
return model_name.lower().rsplit("/", 1)[-1]
|
||||||
|
|
||||||
|
|
||||||
|
def _requires_max_completion_tokens(model_name: str) -> bool:
|
||||||
|
"""Return True for models that reject ``max_tokens`` (GPT-5 family, o3/o4)."""
|
||||||
|
slug = _model_slug(model_name)
|
||||||
|
return "gpt-5" in slug or any(
|
||||||
|
slug == p or slug.startswith((p + "-", p + ".")) for p in ("o3", "o4")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _model_thinking_style(model_name: str) -> str:
|
def _model_thinking_style(model_name: str) -> str:
|
||||||
return _MODEL_THINKING_STYLES.get(_model_slug(model_name), "")
|
return _MODEL_THINKING_STYLES.get(_model_slug(model_name), "")
|
||||||
|
|
||||||
@ -630,7 +638,9 @@ class OpenAICompatProvider(LLMProvider):
|
|||||||
if self._supports_temperature(model_name, reasoning_effort):
|
if self._supports_temperature(model_name, reasoning_effort):
|
||||||
kwargs["temperature"] = temperature
|
kwargs["temperature"] = temperature
|
||||||
|
|
||||||
if spec and getattr(spec, "supports_max_completion_tokens", False):
|
if (
|
||||||
|
spec and getattr(spec, "supports_max_completion_tokens", False)
|
||||||
|
) or _requires_max_completion_tokens(model_name):
|
||||||
kwargs["max_completion_tokens"] = max(1, max_tokens)
|
kwargs["max_completion_tokens"] = max(1, max_tokens)
|
||||||
else:
|
else:
|
||||||
kwargs["max_tokens"] = max(1, max_tokens)
|
kwargs["max_tokens"] = max(1, max_tokens)
|
||||||
|
|||||||
@ -929,6 +929,43 @@ def test_openai_compat_build_kwargs_uses_gpt5_safe_parameters() -> None:
|
|||||||
assert "temperature" not in kwargs
|
assert "temperature" not in kwargs
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("model_name", "expected_key"),
|
||||||
|
[
|
||||||
|
("gpt-5.4", "max_completion_tokens"),
|
||||||
|
("o3-mini", "max_completion_tokens"),
|
||||||
|
("gpt-4", "max_tokens"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_openai_compat_build_kwargs_max_completion_tokens_by_model_name(
|
||||||
|
model_name: str,
|
||||||
|
expected_key: str,
|
||||||
|
) -> None:
|
||||||
|
spec = find_by_name("custom")
|
||||||
|
with patch("nanobot.providers.openai_compat_provider.AsyncOpenAI"):
|
||||||
|
provider = OpenAICompatProvider(
|
||||||
|
api_key="sk-test-key",
|
||||||
|
default_model=model_name,
|
||||||
|
spec=spec,
|
||||||
|
)
|
||||||
|
|
||||||
|
kwargs = provider._build_kwargs(
|
||||||
|
messages=[{"role": "user", "content": "hello"}],
|
||||||
|
tools=None,
|
||||||
|
model=model_name,
|
||||||
|
max_tokens=2048,
|
||||||
|
temperature=0.7,
|
||||||
|
reasoning_effort=None,
|
||||||
|
tool_choice=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
other_key = (
|
||||||
|
"max_tokens" if expected_key == "max_completion_tokens" else "max_completion_tokens"
|
||||||
|
)
|
||||||
|
assert kwargs[expected_key] == 2048
|
||||||
|
assert other_key not in kwargs
|
||||||
|
|
||||||
|
|
||||||
def test_openai_compat_preserves_message_level_reasoning_fields() -> None:
|
def test_openai_compat_preserves_message_level_reasoning_fields() -> None:
|
||||||
with patch("nanobot.providers.openai_compat_provider.AsyncOpenAI"):
|
with patch("nanobot.providers.openai_compat_provider.AsyncOpenAI"):
|
||||||
provider = OpenAICompatProvider()
|
provider = OpenAICompatProvider()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user