101 lines
4 KiB
Python
101 lines
4 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-only
|
|
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
|
|
|
"""Tests that ``_build_openai_passthrough_body`` consults the family
|
|
registry for ``chat_template_kwargs`` and merges them with per-request
|
|
overrides in the correct priority order.
|
|
|
|
Without the registry consult, external OpenAI SDK clients that hit
|
|
``/v1/chat/completions`` with ``tools=[...]`` on a gpt-oss / Nemotron
|
|
model never see the recommended template kwargs reach llama-server,
|
|
even though Studio Chat (which uses the non-passthrough path) gets
|
|
them via a different route.
|
|
"""
|
|
|
|
from models.inference import ChatCompletionRequest
|
|
from routes.inference import _build_openai_passthrough_body
|
|
|
|
|
|
def _make_payload(**fields):
|
|
base = {
|
|
"model": "gpt-oss",
|
|
"messages": [{"role": "user", "content": "hi"}],
|
|
"stream": False,
|
|
}
|
|
base.update(fields)
|
|
return ChatCompletionRequest(**base)
|
|
|
|
|
|
class TestFamilyDefaults:
|
|
def test_gpt_oss_family_default_reaches_outbound(self):
|
|
payload = _make_payload()
|
|
body = _build_openai_passthrough_body(
|
|
payload, model_identifier = "unsloth/gpt-oss-120b-GGUF"
|
|
)
|
|
assert body.get("chat_template_kwargs") == {"reasoning_effort": "medium"}
|
|
|
|
def test_nemotron_family_default_reaches_outbound(self):
|
|
payload = _make_payload()
|
|
body = _build_openai_passthrough_body(
|
|
payload, model_identifier = "unsloth/NVIDIA-Nemotron-3-Super-120B-A12B-GGUF"
|
|
)
|
|
assert body.get("chat_template_kwargs") == {"enable_thinking": True}
|
|
|
|
def test_no_model_identifier_skips_registry(self):
|
|
# Without a model_identifier we cannot look up the family, so
|
|
# behaviour collapses to the prior (request-only) path.
|
|
payload = _make_payload()
|
|
body = _build_openai_passthrough_body(payload)
|
|
assert "chat_template_kwargs" not in body
|
|
|
|
def test_unknown_family_yields_no_template_kwargs(self):
|
|
payload = _make_payload()
|
|
body = _build_openai_passthrough_body(
|
|
payload, model_identifier = "unsloth/CompletelyMadeUp-99B"
|
|
)
|
|
assert "chat_template_kwargs" not in body
|
|
|
|
|
|
class TestPerRequestOverrides:
|
|
def test_explicit_reasoning_effort_wins_over_family(self):
|
|
payload = _make_payload(reasoning_effort = "high")
|
|
body = _build_openai_passthrough_body(
|
|
payload, model_identifier = "unsloth/gpt-oss-120b-GGUF"
|
|
)
|
|
assert body["chat_template_kwargs"]["reasoning_effort"] == "high"
|
|
|
|
def test_extra_body_chat_template_kwargs_wins_outright(self):
|
|
payload = _make_payload(chat_template_kwargs = {"reasoning_effort": "low"})
|
|
body = _build_openai_passthrough_body(
|
|
payload, model_identifier = "unsloth/gpt-oss-120b-GGUF"
|
|
)
|
|
assert body["chat_template_kwargs"]["reasoning_effort"] == "low"
|
|
|
|
def test_enable_thinking_propagates_alongside_family_keys(self):
|
|
# Family carries reasoning_effort, the caller sets enable_thinking.
|
|
# Both should end up in the outbound dict.
|
|
payload = _make_payload(enable_thinking = False)
|
|
body = _build_openai_passthrough_body(
|
|
payload, model_identifier = "unsloth/gpt-oss-120b-GGUF"
|
|
)
|
|
kw = body["chat_template_kwargs"]
|
|
assert kw["reasoning_effort"] == "medium"
|
|
assert kw["enable_thinking"] is False
|
|
|
|
|
|
class TestNoSpuriousKwargs:
|
|
def test_qwen3_no_family_kwargs_emits_no_field(self):
|
|
payload = _make_payload()
|
|
body = _build_openai_passthrough_body(
|
|
payload, model_identifier = "unsloth/Qwen3-8B-GGUF"
|
|
)
|
|
assert "chat_template_kwargs" not in body
|
|
|
|
def test_empty_overrides_collapse_to_no_field(self):
|
|
# No family kwargs and no per-request keys means no outbound
|
|
# field (not an empty dict).
|
|
payload = _make_payload()
|
|
body = _build_openai_passthrough_body(
|
|
payload, model_identifier = "unsloth/Qwen3-8B-GGUF"
|
|
)
|
|
assert "chat_template_kwargs" not in body
|