# 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 for the deterministic MTP VRAM reserve used by load-time auto-fit.

reserve(ctx) = draft_KV(ctx, draft_cache_type) + separate_drafter_weights, sized
from GGUF dims (embedded head from the main model's dims; separate drafter from
its own KV). Anchors checked against real llama-server measurements. Pure: no
GPU, network, subprocess, or GGUF I/O."""

from __future__ import annotations

import inspect
import os
import sys
import types as _types
from pathlib import Path

import pytest

# ---------------------------------------------------------------------------
# Stub heavy/unavailable deps before importing the module under test.
# ---------------------------------------------------------------------------

_BACKEND_DIR = str(Path(__file__).resolve().parent.parent)
if _BACKEND_DIR not in sys.path:
    sys.path.insert(0, _BACKEND_DIR)

_loggers_stub = _types.ModuleType("loggers")
_loggers_stub.get_logger = lambda name: __import__("logging").getLogger(name)
sys.modules.setdefault("loggers", _loggers_stub)

sys.modules.setdefault("structlog", _types.ModuleType("structlog"))

# httpx -- only stub when the real library is missing. Unconditional stubbing
# shadows HTTPError/Response that huggingface_hub.errors imports at load time,
# silently breaking the transformers introspection tier in tests collected after
# this one (the stub leaks via sys.modules for the whole session).
try:
    import httpx as _httpx_real  # noqa: F401
except ImportError:
    _httpx_stub = _types.ModuleType("httpx")
    for _exc_name in (
        "ConnectError",
        "TimeoutException",
        "ReadTimeout",
        "ReadError",
        "RemoteProtocolError",
        "CloseError",
        "HTTPError",
        "RequestError",
    ):
        setattr(_httpx_stub, _exc_name, type(_exc_name, (Exception,), {}))
    _httpx_stub.Timeout = type("Timeout", (), {"__init__": lambda self, *a, **kw: None})
    _httpx_stub.Response = type("Response", (), {})
    _httpx_stub.Client = type(
        "Client",
        (),
        {
            "__init__": lambda self, **kw: None,
            "__enter__": lambda self: self,
            "__exit__": lambda self, *a: None,
        },
    )
    sys.modules["httpx"] = _httpx_stub

from core.inference.llama_cpp import (  # noqa: E402
    _CTX_FIT_VRAM_FRACTION,
    LlamaCppBackend,
    _extra_args_draft_cache_types,
    _extra_args_draft_offloaded_to_cpu,
    _extra_args_mtp_draft_path,
    _extra_args_n_ubatch,
    _extra_args_requests_mtp,
    _extra_args_requests_separate_draft,
    _extra_args_spec_draft_n_max,
    _effective_tensor_parallel,
    _env_main_cache_type_for_budget,
    _extra_args_main_cache_type_for_budget,
    _kv_bytes_per_elem,
    _tensor_parallel_matches_loaded,
)
from core.inference.llama_server_args import _env_split_mode_is_tensor  # noqa: E402

MIB = 1024 * 1024
GIB = 1024**3


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def _make_backend(
    *,
    nextn = 1,
    n_kv_heads = 4,
    n_heads = 24,
    kv_key_length = 256,
    kv_value_length = 256,
    embedding_length = 5120,
    n_layers = 65,
    native_ctx = 262144,
):
    """Qwen3.6-27B-MTP-class backend (embedded head) with the MTP-math dims."""
    b = LlamaCppBackend.__new__(LlamaCppBackend)
    b._nextn_predict_layers = nextn
    b._n_kv_heads = n_kv_heads
    b._n_heads = n_heads
    b._kv_key_length = kv_key_length
    b._kv_value_length = kv_value_length
    b._embedding_length = embedding_length
    b._n_layers = n_layers
    b._context_length = native_ctx
    # Hybrid attention/Mamba (qwen35 path) + remaining KV-estimator fields.
    b._shared_kv_layers = 0
    b._kv_lora_rank = None
    b._sliding_window = None
    b._sliding_window_pattern = None
    b._ssm_inner_size = 6144
    b._full_attention_interval = 4
    b._key_length_mla = None
    b._n_kv_heads_by_layer = None
    b._kv_key_length_swa = None
    b._kv_value_length_swa = None
    b._draft_backend_cache = None
    return b


class _StubDrafter:
    """Stand-in for a separate drafter backend (no GGUF I/O)."""

    def __init__(self, kv_per_token):
        self._kv_per_token = kv_per_token

    def _can_estimate_kv(self):
        return True

    def _estimate_kv_cache_bytes(
        self,
        n_ctx,
        cache_type = None,
        n_parallel = 1,
        **_k,
    ):
        bpe = _kv_bytes_per_elem(cache_type)
        # n_parallel scales like a sliding-window drafter's per-slot KV.
        return 0 if n_ctx <= 0 else int(n_ctx * self._kv_per_token * bpe / 2.0 * n_parallel)


# ---------------------------------------------------------------------------
# Embedded draft KV: deterministic from nextn dims, scales with ctx + draft type
# ---------------------------------------------------------------------------


class TestEmbeddedDraftKv:
    def test_scales_linearly_with_context(self):
        b = _make_backend()
        kv_8k = b._mtp_draft_kv_bytes(8192)
        kv_16k = b._mtp_draft_kv_bytes(16384)
        kv_64k = b._mtp_draft_kv_bytes(65536)
        assert kv_8k and kv_16k and kv_64k
        assert kv_16k == pytest.approx(2 * kv_8k)
        assert kv_64k == pytest.approx(8 * kv_8k)

    def test_value_matches_dim_formula_f16(self):
        # nextn(1) * n_kv(4) * (256+256) * 2(f16) * ctx -- no magic safety factor.
        b = _make_backend()
        ctx = 131072
        expected = int(1 * 4 * 512 * 2.0 * ctx)
        assert b._mtp_draft_kv_bytes(ctx) == expected
        # And that is 512 MiB, matching the measured 27B draft-KV slope (~4 MiB/1k).
        assert b._mtp_draft_kv_bytes(ctx) / MIB == pytest.approx(512, abs = 1)

    def test_scales_with_nextn_predict_layers(self):
        one = _make_backend(nextn = 1)._mtp_draft_kv_bytes(65536)
        two = _make_backend(nextn = 2)._mtp_draft_kv_bytes(65536)
        assert two == pytest.approx(2 * one)

    def test_embedded_draft_kv_floored_at_f16(self):
        # The embedded MTP head is one layer, so llama.cpp's quantized-KV
        # overhead is not amortized: a quantized draft KV fits LESS context than
        # f16, not more (ggml-org/llama.cpp#24102). The embedded reserve floors a
        # quantized draft type at f16 (never under-reserved); f32 still costs more.
        b = _make_backend()
        f16 = b._mtp_draft_kv_bytes(65536, draft_cache_type_k = "f16", draft_cache_type_v = "f16")
        q8 = b._mtp_draft_kv_bytes(65536, draft_cache_type_k = "q8_0", draft_cache_type_v = "q8_0")
        q4 = b._mtp_draft_kv_bytes(65536, draft_cache_type_k = "q4_0", draft_cache_type_v = "q4_0")
        f32 = b._mtp_draft_kv_bytes(65536, draft_cache_type_k = "f32", draft_cache_type_v = "f32")
        assert q8 == f16 and q4 == f16  # quantized draft KV priced as f16, not less
        assert f32 == pytest.approx(f16 * 2.0)  # f32 genuinely larger, not floored

    def test_draft_kv_split_axes_no_under_reserve(self):
        # A quantized draft type on either or both axes never reserves below the
        # all-f16 value for the single-layer embedded head (the f16 floor; #24102).
        b = _make_backend()
        both_q4 = b._mtp_draft_kv_bytes(
            131072, draft_cache_type_k = "q4_0", draft_cache_type_v = "q4_0"
        )
        k_only = b._mtp_draft_kv_bytes(131072, draft_cache_type_k = "q4_0")  # V defaults f16
        both_f16 = b._mtp_draft_kv_bytes(131072, draft_cache_type_k = "f16", draft_cache_type_v = "f16")
        assert both_q4 == k_only == both_f16  # floored at f16, never under-reserved

    def test_none_when_dims_missing(self):
        assert _make_backend(nextn = 0)._mtp_draft_kv_bytes(65536) is None
        assert _make_backend(kv_key_length = None)._mtp_draft_kv_bytes(65536) is None
        assert _make_backend()._mtp_draft_kv_bytes(0) is None


# ---------------------------------------------------------------------------
# Separate drafter (Gemma): sized from the drafter GGUF's own dims + weights
# ---------------------------------------------------------------------------


class TestSeparateDrafter:
    def test_uses_drafter_kv_and_weights(self, monkeypatch):
        b = _make_backend(nextn = None)  # main has no embedded head
        stub = _StubDrafter(kv_per_token = 2000)
        monkeypatch.setattr(b, "_draft_backend_for", lambda path: stub)
        ctx = 65536
        kv = b._mtp_draft_kv_bytes(ctx, drafter_path = "/m/draft.gguf")
        assert kv == stub._estimate_kv_cache_bytes(ctx)
        total = b._estimate_mtp_overhead_bytes(
            ctx, drafter_path = "/m/draft.gguf", draft_weights_bytes = GIB
        )
        assert total == kv + GIB

    def test_drafter_kv_scales_with_context(self, monkeypatch):
        b = _make_backend(nextn = None)
        monkeypatch.setattr(b, "_draft_backend_for", lambda path: _StubDrafter(2000))
        a = b._mtp_draft_kv_bytes(16384, drafter_path = "/m/d.gguf")
        c = b._mtp_draft_kv_bytes(65536, drafter_path = "/m/d.gguf")
        assert c == pytest.approx(4 * a)

    def test_drafter_kv_scales_with_parallel_slots(self, monkeypatch):
        # The drafter is served under the same --parallel slots as the main model,
        # so a sliding-window drafter's KV grows per slot; the reserve must thread
        # n_parallel or it under-reserves (Finding G1).
        b = _make_backend(nextn = None)
        monkeypatch.setattr(b, "_draft_backend_for", lambda path: _StubDrafter(2000))
        one = b._mtp_draft_kv_bytes(65536, drafter_path = "/m/d.gguf", n_parallel = 1)
        four = b._mtp_draft_kv_bytes(65536, drafter_path = "/m/d.gguf", n_parallel = 4)
        assert four == pytest.approx(4 * one)
        # And it threads through the overhead estimate too.
        ov1 = b._estimate_mtp_overhead_bytes(
            65536, drafter_path = "/m/d.gguf", draft_weights_bytes = GIB, n_parallel = 1
        )
        ov4 = b._estimate_mtp_overhead_bytes(
            65536, drafter_path = "/m/d.gguf", draft_weights_bytes = GIB, n_parallel = 4
        )
        assert (ov4 - GIB) == pytest.approx(4 * (ov1 - GIB))  # KV scales, weights flat

    def test_none_when_drafter_unreadable(self, monkeypatch):
        b = _make_backend(nextn = None)
        monkeypatch.setattr(b, "_draft_backend_for", lambda path: None)
        assert b._mtp_draft_kv_bytes(65536, drafter_path = "/m/d.gguf") is None
        assert b._estimate_mtp_overhead_bytes(65536, drafter_path = "/m/d.gguf") is None

    def test_keeps_weights_when_drafter_kv_unsizable(self, monkeypatch):
        # KV can't be sized (exotic/remote drafter), but the local weights are
        # known: reserve the weights so a drafter larger than the flat fallback
        # cushion can't slip through and OOM (Finding C). Nothing known -> None.
        b = _make_backend(nextn = None)
        monkeypatch.setattr(b, "_draft_backend_for", lambda path: None)
        assert b._mtp_draft_kv_bytes(65536, drafter_path = "/m/d.gguf") is None
        assert (
            b._estimate_mtp_overhead_bytes(
                65536, drafter_path = "/m/d.gguf", draft_weights_bytes = 3 * GIB
            )
            == 3 * GIB
        )
        assert b._estimate_mtp_overhead_bytes(65536, drafter_path = "/m/d.gguf") is None


# ---------------------------------------------------------------------------
# Total overhead = draft KV (+ separate drafter weights); no verify constant
# ---------------------------------------------------------------------------


class TestOverheadTotal:
    def test_equals_draft_kv_for_embedded(self):
        b = _make_backend()
        for ctx in (16384, 65536, 131072):
            assert b._estimate_mtp_overhead_bytes(ctx) == b._mtp_draft_kv_bytes(ctx)

    def test_does_not_depend_on_n_max(self):
        # The verify buffer (the only n_max-dependent term) rides in headroom now.
        b = _make_backend()
        assert b._estimate_mtp_overhead_bytes(
            65536, spec_draft_n_max = 2
        ) == b._estimate_mtp_overhead_bytes(65536, spec_draft_n_max = 6)

    def test_none_when_draft_kv_unsizable(self):
        assert _make_backend(nextn = 0)._estimate_mtp_overhead_bytes(65536) is None

    def test_includes_separate_drafter_weights(self):
        b = _make_backend()
        base = b._estimate_mtp_overhead_bytes(65536)
        with_w = b._estimate_mtp_overhead_bytes(65536, draft_weights_bytes = GIB)
        assert with_w - base == GIB

    @pytest.mark.parametrize(
        "ctx,measured_draft_kv_mib",
        # Measured 27B MTP delta minus the (headroom-covered) ~500 MiB verify
        # buffer leaves the draft KV; the deterministic estimate must match it.
        [(16384, 64), (65536, 256), (131072, 512)],
    )
    def test_draft_kv_matches_measured(self, ctx, measured_draft_kv_mib):
        b = _make_backend()
        pred = b._estimate_mtp_overhead_bytes(ctx) / MIB
        assert pred == pytest.approx(measured_draft_kv_mib, abs = 2)


# ---------------------------------------------------------------------------
# _fit_context_to_vram: MTP reserve lowers the chosen context
# ---------------------------------------------------------------------------


class TestFitContextWithMtp:
    def _fit_backend(self, kv_per_token = 325_000):
        b = _make_backend()
        b._can_estimate_kv = lambda: True
        b._estimate_kv_cache_bytes = lambda n, _t = None, **_k: (0 if n <= 0 else n * kv_per_token)
        return b

    def test_overhead_fn_lowers_context(self):
        b = self._fit_backend()
        avail_mib = 24_000
        model = 8 * GIB
        without = b._fit_context_to_vram(131072, avail_mib, model)
        with_mtp = b._fit_context_to_vram(
            131072,
            avail_mib,
            model,
            mtp_overhead_fn = lambda c: b._estimate_mtp_overhead_bytes(c) or 0,
        )
        assert 0 < with_mtp < without

    def test_quantized_embedded_draft_kv_does_not_inflate_context(self):
        # For the single-layer embedded head, quantizing the draft KV does NOT
        # buy more context (it fits less in practice; ggml-org/llama.cpp#24102),
        # so the f16-floored reserve advertises the same context as f16 -- never
        # a larger one off a smaller (unsafe) reserve.
        b = self._fit_backend()
        avail_mib, model = 24_000, 8 * GIB
        f16 = b._fit_context_to_vram(
            131072,
            avail_mib,
            model,
            mtp_overhead_fn = lambda c: b._estimate_mtp_overhead_bytes(
                c, draft_cache_type_k = "f16", draft_cache_type_v = "f16"
            )
            or 0,
        )
        q4 = b._fit_context_to_vram(
            131072,
            avail_mib,
            model,
            mtp_overhead_fn = lambda c: b._estimate_mtp_overhead_bytes(
                c, draft_cache_type_k = "q4_0", draft_cache_type_v = "q4_0"
            )
            or 0,
        )
        assert 0 < q4 == f16

    def test_no_mtp_unchanged(self):
        b = self._fit_backend()
        avail_mib, model = 24_000, 8 * GIB
        a = b._fit_context_to_vram(131072, avail_mib, model)
        bb = b._fit_context_to_vram(
            131072, avail_mib, model, mtp_engaged = False, mtp_overhead_fn = None
        )
        assert a == bb

    def test_chosen_context_actually_fits_budget(self):
        b = self._fit_backend()
        avail_mib, model = 24_000, 8 * GIB
        fn = lambda c: b._estimate_mtp_overhead_bytes(c) or 0  # noqa: E731
        ctx = b._fit_context_to_vram(131072, avail_mib, model, mtp_overhead_fn = fn)
        budget = avail_mib * MIB * _CTX_FIT_VRAM_FRACTION
        assert model + b._estimate_kv_cache_bytes(ctx) + fn(ctx) <= budget


# ---------------------------------------------------------------------------
# extra_args parsing: detect user-enabled MTP + draft depth + draft KV type
# ---------------------------------------------------------------------------


class TestExtraArgsMtpDetection:
    @pytest.mark.parametrize(
        "args,expected",
        [
            (["--spec-type", "draft-mtp"], True),
            (["--spec-type", "mtp"], True),
            (["--spec-type", "ngram-mod,draft-mtp"], True),
            (["--spec-type=draft-mtp"], True),
            (["--spec-type", "ngram-mod"], False),
            (["--spec-default"], False),
            (["-c", "131072"], False),
            (None, False),
            ([], False),
        ],
    )
    def test_requests_mtp(self, args, expected):
        assert _extra_args_requests_mtp(args, env = {}) is expected

    def test_requests_mtp_env(self):
        # The child honors LLAMA_ARG_SPEC_TYPE; env-requested MTP must reserve too.
        assert _extra_args_requests_mtp([], env = {"LLAMA_ARG_SPEC_TYPE": "draft-mtp"}) is True
        assert _extra_args_requests_mtp([], env = {"LLAMA_ARG_SPEC_TYPE": "ngram-mod,mtp"}) is True
        assert _extra_args_requests_mtp([], env = {"LLAMA_ARG_SPEC_TYPE": "draft-simple"}) is False
        assert _extra_args_requests_mtp([], env = {"LLAMA_ARG_SPEC_TYPE": "none"}) is False

    def test_requests_mtp_effective_spec_type(self):
        # llama.cpp uses the LAST CLI --spec-type and ignores the env when any CLI
        # --spec-type is present. The reserve must track that effective value, not
        # any earlier/MTP-ish one, or it over-reserves a drafter the launch won't
        # load (Finding B).
        env_mtp = {"LLAMA_ARG_SPEC_TYPE": "draft-mtp"}
        # Later CLI value overrides an earlier MTP one (last-wins).
        assert (
            _extra_args_requests_mtp(
                ["--spec-type", "draft-mtp", "--spec-type", "ngram-mod"], env = {}
            )
            is False
        )
        # A non-MTP CLI flag overrides a stale MTP env.
        assert _extra_args_requests_mtp(["--spec-type", "ngram-mod"], env = env_mtp) is False
        assert _extra_args_requests_mtp(["--spec-type", "none"], env = env_mtp) is False
        # A later MTP CLI value still engages.
        assert (
            _extra_args_requests_mtp(
                ["--spec-type", "ngram-mod", "--spec-type", "draft-mtp"], env = {}
            )
            is True
        )
        # Same precedence for separate (draft-simple/eagle3) detection.
        assert (
            _extra_args_requests_separate_draft(
                ["--spec-type", "draft-simple", "--spec-type", "ngram-mod"], env = {}
            )
            is False
        )
        assert (
            _extra_args_requests_separate_draft(
                ["--spec-type", "ngram-mod"], env = {"LLAMA_ARG_SPEC_TYPE": "draft-simple"}
            )
            is False
        )

    @pytest.mark.parametrize(
        "args,expected",
        [
            (["--spec-type", "draft-simple"], True),
            (["--spec-type", "draft-eagle3"], True),
            (["--spec-type=draft-eagle3"], True),
            (["--spec-type", "draft-mtp"], False),  # MTP path handles this one
            (["--spec-type", "ngram-mod"], False),  # loads no draft model
            (["-c", "4096"], False),
            (None, False),
        ],
    )
    def test_requests_separate_draft(self, args, expected):
        assert _extra_args_requests_separate_draft(args, env = {}) is expected

    def test_requests_separate_draft_env(self):
        assert (
            _extra_args_requests_separate_draft([], env = {"LLAMA_ARG_SPEC_TYPE": "draft-simple"})
            is True
        )
        assert (
            _extra_args_requests_separate_draft([], env = {"LLAMA_ARG_SPEC_TYPE": "draft-mtp"})
            is False
        )

    def test_load_model_reserves_for_non_mtp_draft_modes(self):
        # load_model engages the draft reserve for a non-MTP model-based draft mode
        # only when extras also name a drafter (else nothing is loaded to reserve).
        # Strip all whitespace so the check survives any line-wrapping the
        # formatter applies to the call (pre-commit black wraps long lines).
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_user_draft_via_extras" in compact
        # called with extra_args (an env kwarg may follow); prefix match stays
        # robust to that and to any formatter line-wrapping.
        assert "_extra_args_requests_separate_draft(extra_args" in compact
        assert "or_user_draft_via_extras" in compact  # OR'd into the reserve gate
        # The drafter check must NOT force extras-only (env={}); the default
        # env=None lets it see an env LLAMA_ARG_SPEC_DRAFT_MODEL, so an env-only
        # drafter still engages the reserve (codex review 4507014299).
        assert "bool(_extra_args_mtp_draft_path(extra_args))" in compact

    def test_env_only_drafter_engages_separate_draft_reserve(self, monkeypatch):
        # An env-provided drafter (no --model-draft in extras) must still engage
        # the draft reserve, or auto-fit spends the drafter's VRAM and OOMs. Mirror
        # load_model's _user_draft_via_extras gate (codex review 4507014299).
        monkeypatch.setenv("LLAMA_ARG_SPEC_DRAFT_MODEL", "/large.gguf")
        monkeypatch.delenv("LLAMA_ARG_SPEC_DRAFT_HF_REPO", raising = False)
        ea = ["--spec-type", "draft-simple"]  # _spec_env is {} (extras set spec-type)
        assert _extra_args_requests_separate_draft(ea, env = {}) is True
        assert _extra_args_mtp_draft_path(ea) == "/large.gguf"  # env=None -> os.environ
        # -> _user_draft_via_extras True; _env_draft_for_budget sizes the drafter.
        assert _extra_args_mtp_draft_path([], env = dict(os.environ)) == "/large.gguf"

    def test_load_model_gates_env_spec_type_on_off_mode(self):
        # LLAMA_ARG_SPEC_TYPE only reaches the child when Studio emits no spec
        # flag (UI mode "off", no user --spec-type); otherwise the emitted
        # --spec-type/--spec-default overrides the env, so the reserve must not
        # consult it or a stale MTP env over-reserves (Finding F3). Whitespace-
        # stripped so the check survives formatter line-wrapping.
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert '_mtp_canonical=="off"' in compact  # the env-reaches-child gate
        assert "_extra_args_requests_mtp(extra_args,env=_spec_env)" in compact

    def test_spec_default_overrides_env_mtp(self):
        # --spec-default is a CLI spec flag (resolves to the model default,
        # non-MTP) that overrides a stale LLAMA_ARG_SPEC_TYPE env, so the reserve
        # must not treat it as MTP (reviewer.py R4).
        env_mtp = {"LLAMA_ARG_SPEC_TYPE": "draft-mtp"}
        assert _extra_args_requests_mtp(["--spec-default"], env = env_mtp) is False
        assert (
            _extra_args_requests_separate_draft(
                ["--spec-default"], env = {"LLAMA_ARG_SPEC_TYPE": "draft-simple"}
            )
            is False
        )
        # A later --spec-type still wins over an earlier --spec-default.
        assert (
            _extra_args_requests_mtp(["--spec-default", "--spec-type", "draft-mtp"], env = {}) is True
        )

    def test_load_model_drafter_budget_precedence(self):
        # The budget sizes the drafter the launch actually loads: CLI extras win,
        # then Studio's emitted mtp_draft_path (overrides LLAMA_ARG_SPEC_DRAFT_MODEL),
        # then the env drafter -- not the env before Studio's (reviewer.py R3).
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_cli_draft_for_budget=_extra_args_mtp_draft_path(extra_args,env={})" in compact
        assert "_env_draft_for_budget=_extra_args_mtp_draft_path([],env=os.environ)" in compact
        assert "_cli_draft_for_budgetor_studio_draft_for_budgetor_env_draft_for_budget" in compact

    def test_load_model_drops_cpu_offloaded_drafter_from_budget(self):
        # A SEPARATE drafter offloaded to CPU (--spec-draft-ngl 0 /
        # --spec-draft-device none) consumes no GPU, so it must be dropped from the
        # budget and get no flat reserve (Finding F2). But an embedded head is on
        # GPU regardless of those draft-only flags, so the flat reserve is only
        # suppressed when there is no embedded head (Finding G5).
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        # env-aware: also honors the inherited LLAMA_ARG_N_GPU_LAYERS_DRAFT.
        assert (
            "_draft_on_cpu=_extra_args_draft_offloaded_to_cpu(extra_args,env=os.environ)" in compact
        )
        assert "if_draft_on_cpu:_mtp_draft_for_budget=None" in compact
        # flat reserve suppressed only for a CPU drafter with no embedded head
        assert "_draft_cpu_no_embedded=_draft_on_cpuandnotself._nextn_predict_layers" in compact
        assert "not_draft_cpu_no_embedded" in compact

    def test_load_model_keeps_flat_reserve_for_unsized_draft_kv(self):
        # When only the drafter weights could be sized (KV unsizable), the flat
        # fraction stays on as the cushion for the still-unsized draft KV, on top
        # of the byte-accurate weights reserve (Finding G3).
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_mtp_kv_unsized" in compact
        assert "mtp_overhead_fnisNoneor_mtp_kv_unsized" in compact

    def test_load_model_ranks_subsets_by_active_pin_fraction(self):
        # Auto/cap subset ranking uses the active budget fraction (lowered by the
        # flat MTP reserve), not a hard-coded 0.95, so the ranking order matches
        # the fit budget that is then tested (Finding G4).
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_gpu_usable(g,pin_fraction)" in compact
        assert "_gpu_usable(g,_CTX_FIT_VRAM_FRACTION-_flat_mtp_reserve)" in compact

    @pytest.mark.parametrize(
        "args,expected",
        [
            (["--spec-draft-ngl", "0"], True),
            (["-ngld", "0"], True),
            (["--spec-draft-ngl=0"], True),
            (["--n-gpu-layers-draft", "0"], True),
            (["--spec-draft-ngl", "20"], False),
            (["--spec-draft-device", "none"], True),
            (["--spec-draft-device", "CPU"], True),
            (["-devd", "cpu,none"], True),
            (["--spec-draft-device", "CUDA0"], False),
            (["--spec-draft-device", "CUDA0,CPU"], False),  # any GPU -> on GPU
            (["-c", "4096"], False),
            (None, False),
            # last-wins: only the final value of each flag counts (Finding G2)
            (["--spec-draft-ngl", "0", "--spec-draft-ngl", "-1"], False),  # last = GPU
            (["--spec-draft-ngl", "-1", "--spec-draft-ngl", "0"], True),  # last = CPU
            (["--spec-draft-device", "CUDA0", "--spec-draft-device", "none"], True),
            (["--spec-draft-device", "none", "--spec-draft-device", "CUDA0"], False),
        ],
    )
    def test_draft_offloaded_to_cpu(self, args, expected):
        assert _extra_args_draft_offloaded_to_cpu(args, env = {}) is expected

    def test_draft_offloaded_to_cpu_env(self):
        # The child honors LLAMA_ARG_N_GPU_LAYERS_DRAFT; an env-only CPU offload
        # must drop the drafter from the budget too (review run3 #3). CLI wins.
        assert (
            _extra_args_draft_offloaded_to_cpu([], env = {"LLAMA_ARG_N_GPU_LAYERS_DRAFT": "0"})
            is True
        )
        assert (
            _extra_args_draft_offloaded_to_cpu([], env = {"LLAMA_ARG_N_GPU_LAYERS_DRAFT": "-1"})
            is False
        )
        # CLI --spec-draft-ngl wins over the env (last-wins is CLI-only).
        assert (
            _extra_args_draft_offloaded_to_cpu(
                ["--spec-draft-ngl", "-1"], env = {"LLAMA_ARG_N_GPU_LAYERS_DRAFT": "0"}
            )
            is False
        )
        assert _extra_args_draft_offloaded_to_cpu([], env = {}) is False

    @pytest.mark.parametrize(
        "args,expected",
        [
            (["--spec-draft-n-max", "4"], 4),
            (["--spec-draft-n-max=6"], 6),
            (["--spec-type", "draft-mtp", "--spec-draft-n-max", "3"], 3),
            (["--spec-draft-n-max", "2", "--spec-draft-n-max", "5"], 5),  # last wins
            (["--spec-draft-n-max", "notanint"], None),
            (["-c", "4096"], None),
            (None, None),
            (["--draft-max", "6"], 6),
            (["--draft-max=4"], 4),
            (["--spec-type", "draft-mtp", "--draft-max", "6"], 6),
            (["--spec-draft-n-max", "2", "--draft-max", "5"], 5),
        ],
    )
    def test_spec_draft_n_max(self, args, expected):
        assert _extra_args_spec_draft_n_max(args) == expected

    @pytest.mark.parametrize(
        "args,expected",
        [
            (["--model-draft", "/m/draft.gguf"], "/m/draft.gguf"),
            (["--spec-draft-model", "/m/draft.gguf"], "/m/draft.gguf"),
            (["-md", "/m/draft.gguf"], "/m/draft.gguf"),
            (["--model-draft=/m/draft.gguf"], "/m/draft.gguf"),
            (["--model-draft", "--spec-type"], None),
            (["-c", "4096"], None),
            (None, None),
        ],
    )
    def test_mtp_draft_path(self, args, expected):
        # env={} isolates pure-CLI behavior from a polluted test environment.
        assert _extra_args_mtp_draft_path(args, env = {}) == expected

    @pytest.mark.parametrize(
        "args,expected",
        [
            # HF draft repo flags are real llama-server flags; the budget must see them.
            (["--spec-draft-hf", "big/repo:Q8_0"], "big/repo:Q8_0"),
            (["-hfd", "big/repo"], "big/repo"),
            (["-hfrd", "big/repo"], "big/repo"),
            (["--hf-repo-draft=big/repo"], "big/repo"),
        ],
    )
    def test_mtp_draft_path_hf_flags(self, args, expected):
        assert _extra_args_mtp_draft_path(args, env = {}) == expected

    def test_mtp_draft_path_env_fallback(self):
        # The child honors LLAMA_ARG_SPEC_DRAFT_MODEL / _HF_REPO; CLI wins over env.
        assert (
            _extra_args_mtp_draft_path([], env = {"LLAMA_ARG_SPEC_DRAFT_MODEL": "/m/e.gguf"})
            == "/m/e.gguf"
        )
        assert _extra_args_mtp_draft_path([], env = {"LLAMA_ARG_SPEC_DRAFT_HF_REPO": "x/y"}) == "x/y"
        assert (
            _extra_args_mtp_draft_path(
                ["-md", "/m/cli.gguf"], env = {"LLAMA_ARG_SPEC_DRAFT_HF_REPO": "x/y"}
            )
            == "/m/cli.gguf"
        )

    @pytest.mark.parametrize(
        "args,expected",
        [
            (["--cache-type-k-draft", "q8_0"], ("q8_0", None)),
            (["--spec-draft-type-k", "q4_0"], ("q4_0", None)),
            (["-ctkd", "q8_0"], ("q8_0", None)),
            (["--cache-type-v-draft", "q4_0"], (None, "q4_0")),  # K stays f16, V only
            (["--cache-type-k-draft", "q4_0", "--cache-type-v-draft", "q8_0"], ("q4_0", "q8_0")),
            (["--cache-type-k-draft=q8_0"], ("q8_0", None)),
            (["--cache-type-k", "q8_0"], (None, None)),  # main type, not draft
            (["-c", "4096"], (None, None)),
            (None, (None, None)),
        ],
    )
    def test_draft_cache_types(self, args, expected):
        assert _extra_args_draft_cache_types(args, env = {}) == expected

    def test_draft_cache_types_env_fallback(self):
        # The child honors LLAMA_ARG_SPEC_DRAFT_CACHE_TYPE_K/_V per axis; CLI wins.
        assert _extra_args_draft_cache_types(
            [], env = {"LLAMA_ARG_SPEC_DRAFT_CACHE_TYPE_K": "q8_0"}
        ) == ("q8_0", None)
        assert _extra_args_draft_cache_types(
            [],
            env = {
                "LLAMA_ARG_SPEC_DRAFT_CACHE_TYPE_K": "q8_0",
                "LLAMA_ARG_SPEC_DRAFT_CACHE_TYPE_V": "q4_0",
            },
        ) == ("q8_0", "q4_0")
        assert _extra_args_draft_cache_types(
            ["-ctkd", "q4_0"], env = {"LLAMA_ARG_SPEC_DRAFT_CACHE_TYPE_K": "q8_0"}
        ) == ("q4_0", None)

    @pytest.mark.parametrize(
        "args,expected",
        [
            (["--ubatch-size", "1024"], 1024),
            (["-ub", "4096"], 4096),
            (["--ubatch-size=512"], 512),
            (["--ubatch", "2048"], None),  # not a real llama-server flag; ignore it
            (["-c", "4096"], None),
            (None, None),
        ],
    )
    def test_n_ubatch(self, args, expected):
        assert _extra_args_n_ubatch(args, env = {}) == expected

    def test_n_ubatch_env_fallback(self):
        # The child honors LLAMA_ARG_UBATCH; it must reach the compute-buffer reserve.
        assert _extra_args_n_ubatch([], env = {"LLAMA_ARG_UBATCH": "4096"}) == 4096
        assert (
            _extra_args_n_ubatch(["-ub", "1024"], env = {"LLAMA_ARG_UBATCH": "4096"}) == 1024
        )  # CLI wins
        assert _extra_args_n_ubatch([], env = {"LLAMA_ARG_UBATCH": "notint"}) is None

    def test_env_main_cache_type_for_budget(self):
        # The child inherits LLAMA_ARG_CACHE_TYPE_K/_V, but Studio emits no
        # --cache-type when neither param nor extras set it -> a heavier env
        # main KV (f32) must be adopted so the reserve matches the child.
        assert _env_main_cache_type_for_budget(env = {}) is None
        # f32 exceeds the f16 default -> adopt it (lower-cased so the launch
        # re-emits it via _valid_cache_types).
        assert _env_main_cache_type_for_budget(env = {"LLAMA_ARG_CACHE_TYPE_K": "f32"}) == "f32"
        assert _env_main_cache_type_for_budget(env = {"LLAMA_ARG_CACHE_TYPE_V": "F32"}) == "f32"
        # Heavier of K/V (single knob; over-reserves the lighter axis).
        assert (
            _env_main_cache_type_for_budget(
                env = {"LLAMA_ARG_CACHE_TYPE_K": "f32", "LLAMA_ARG_CACHE_TYPE_V": "f16"}
            )
            == "f32"
        )
        # Quantized env types are <= f16 -> already over-reserved by the default.
        assert _env_main_cache_type_for_budget(env = {"LLAMA_ARG_CACHE_TYPE_K": "q4_0"}) is None
        assert _env_main_cache_type_for_budget(env = {"LLAMA_ARG_CACHE_TYPE_V": "q8_0"}) is None
        assert _env_main_cache_type_for_budget(env = {"LLAMA_ARG_CACHE_TYPE_K": "f16"}) is None
        # Unknown env type self-neutralizes (treated as f16 by _kv_bytes_per_elem).
        assert _env_main_cache_type_for_budget(env = {"LLAMA_ARG_CACHE_TYPE_K": "wat"}) is None

    def test_load_model_adopts_env_main_cache_type(self):
        # Source-level: load_model budgets the heavier of asymmetric --cache-type
        # extras, then (only when neither param nor extras set it) adopts the env
        # main KV type, so the reserve covers a child that inherits a heavier
        # LLAMA_ARG_CACHE_TYPE_*. Whitespace-stripped to survive formatter wraps.
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_extra_args_main_cache_type_for_budget(extra_args)" in compact
        assert "ifcache_type_kvisNone:" in compact
        assert "cache_type_kv=_env_main_cache_type_for_budget()" in compact

    def test_env_split_mode_is_tensor(self):
        # The child inherits LLAMA_ARG_SPLIT_MODE, but Studio emits --split-mode
        # only on its tensor branch -> a tensor env must flip the budget so the
        # heavier per-device compute buffer is reserved (not layer overhead).
        assert _env_split_mode_is_tensor(env = {}) is False
        assert _env_split_mode_is_tensor(env = {"LLAMA_ARG_SPLIT_MODE": "tensor"}) is True
        assert _env_split_mode_is_tensor(env = {"LLAMA_ARG_SPLIT_MODE": "Tensor"}) is True
        # Other modes are not a runtime-heavier surprise -> not acted on.
        assert _env_split_mode_is_tensor(env = {"LLAMA_ARG_SPLIT_MODE": "layer"}) is False
        assert _env_split_mode_is_tensor(env = {"LLAMA_ARG_SPLIT_MODE": "row"}) is False
        assert _env_split_mode_is_tensor(env = {"LLAMA_ARG_SPLIT_MODE": "none"}) is False

    def test_effective_tensor_parallel_env_flip(self):
        # Shared by load_model and both duplicate-load matchers, so they agree.
        tensor_env = {"LLAMA_ARG_SPLIT_MODE": "tensor"}
        # No extras, toggle off, tensor env -> flips on.
        assert _effective_tensor_parallel(None, False, env = tensor_env) is True
        # Extras override (any --split-mode) beats the env, even if non-tensor.
        assert _effective_tensor_parallel(["--split-mode", "layer"], False, env = tensor_env) is False
        # Explicit extras/toggle tensor stays on regardless of env.
        assert _effective_tensor_parallel(["--split-mode", "tensor"], False, env = {}) is True
        assert _effective_tensor_parallel(None, True, env = {}) is True
        # One-directional: a non-tensor env never downgrades, and no env -> no flip.
        assert _effective_tensor_parallel(None, False, env = {}) is False
        assert (
            _effective_tensor_parallel(None, False, env = {"LLAMA_ARG_SPLIT_MODE": "layer"}) is False
        )

    def test_tensor_parallel_matches_loaded_env_downgrade(self):
        # Env-only tensor matches a server that actually launched tensor, but a
        # server load_model downgraded to layer (env scrubbed) must still match
        # an identical request -- not reload forever (#6312).
        tensor_env = {"LLAMA_ARG_SPLIT_MODE": "tensor"}
        # Launched tensor: env-only request matches.
        assert _tensor_parallel_matches_loaded(None, False, True, env = tensor_env) is True
        # Downgraded to layer: same env-only request still matches (no reload loop).
        assert _tensor_parallel_matches_loaded(None, False, False, env = tensor_env) is True
        # No env: a plain request matches a layer server and mismatches a tensor one.
        assert _tensor_parallel_matches_loaded(None, False, False, env = {}) is True
        assert _tensor_parallel_matches_loaded(None, False, True, env = {}) is False
        # Explicit tensor request stays strict: must have a tensor server.
        assert _tensor_parallel_matches_loaded(None, True, False, env = {}) is False
        assert _tensor_parallel_matches_loaded(None, True, True, env = {}) is True
        # An explicit non-tensor --split-mode beats the env (no flip).
        assert (
            _tensor_parallel_matches_loaded(["--split-mode", "layer"], False, True, env = tensor_env)
            is False
        )

    def test_route_matcher_uses_tensor_parallel_matches_loaded(self):
        # Fix: the route duplicate-load matcher must use the downgrade-aware
        # helper, or an env-driven tensor server (or its layer downgrade) is
        # needlessly reloaded (#6312). Read from disk (importing routes.inference
        # drags in heavy deps).
        routes_src = (
            Path(__file__).resolve().parent.parent / "routes" / "inference.py"
        ).read_text()
        start = routes_src.index("def _request_matches_loaded_settings")
        end = routes_src.index("\ndef ", start + 1)
        body = "".join(routes_src[start:end].split())
        assert (
            "_tensor_parallel_matches_loaded(effective_extra,"
            "request.tensor_parallel,llama_backend.tensor_parallel)" in body
        )

    def test_route_matcher_retries_after_drafter_not_found(self):
        # drafter_not_found must not report "already loaded" or the reload never
        # retries the download (#6459). Read source: importing routes pulls deps.
        routes_src = (
            Path(__file__).resolve().parent.parent / "routes" / "inference.py"
        ).read_text()
        start = routes_src.index("def _request_matches_loaded_settings")
        end = routes_src.index("\ndef ", start + 1)
        body = "".join(routes_src[start:end].split())
        assert 'llama_backend.spec_fallback_reason=="drafter_not_found"' in body
        assert "not_extra_args_set_spec_type(effective_extra)" in body
        # HF-only (hf_repo): local/native loads have no download to retry.
        assert "llama_backend.hf_repo" in body

    def test_extra_args_main_cache_type_heavier_axis(self):
        # Asymmetric --cache-type-k/-v must budget the heavier axis (extras win
        # per axis at launch), not the last-wins single type that under-reserves.
        H = _extra_args_main_cache_type_for_budget
        assert H(["--cache-type-k", "f32", "--cache-type-v", "f16"]) == "f32"
        assert H(["--cache-type-v", "f16", "--cache-type-k", "f32"]) == "f32"  # order-free
        assert H(["--cache-type-k=f32", "--cache-type-v=f16"]) == "f32"  # = form
        assert H(["-ctk", "q4_0", "-ctv", "q8_0"]) == "q8_0"  # heavier quant
        assert H(["--cache-type-k", "q8_0"]) == "q8_0"  # single axis honored as-is
        assert H(["-c", "4096"]) is None  # no cache flags
        assert H(None) is None

    def test_load_model_budgets_heavier_asymmetric_cache_axis(self):
        # load_model must reserve from the heavier of asymmetric cache extras, or
        # an f32 K against an f16 budget over-advertises context and can OOM.
        load = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_extra_args_main_cache_type_for_budget(extra_args)" in load

    def test_load_model_tensor_drops_any_quantized_cache_axis(self):
        # The heavier-by-bytes budget type can mask a quantized axis (an f16
        # budget hides a paired q4_0), so the tensor-safety drop must test each
        # --cache-type-k/-v extra, not just cache_type_kv -- else the quantized
        # axis survives into tensor mode and crashes the load (#6312).
        load = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_ck_extra,_cv_extra=parse_cache_override_per_axis(extra_args)" in load
        assert "forcin(cache_type_kv,_ck_extra,_cv_extra)" in load
        assert "iftensor_paralleland_cache_non_tensor_safe:" in load

    def test_load_model_layer_downgrade_restores_original_cache_extras(self):
        # Tensor mode strips asymmetric --cache-type-k/-v (it rejects quantized),
        # but layer split supports them, so a downgrade must restore the ORIGINAL
        # extras, not just the scalar heavier type (else q4_0/f16 silently becomes
        # f16/f16 on the layer fallback) (#6312).
        load = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_tensor_dropped_extra_args=list(extra_args)" in load
        # The original extras are restored via one shared closure, called at all
        # three tensor->layer downgrade points.
        assert "strip_split_mode_only(_tensor_dropped_extra_argsif" in load
        assert load.count("_restore_after_tensor_downgrade()") >= 3

    def test_load_model_tensor_skips_reserve_for_cpu_drafter(self):
        # A separate CPU-offloaded drafter (no embedded head) uses no GPU, so the
        # tensor reserve must be suppressed like the layer path -- else tensor mode
        # subtracts a phantom flat MTP reserve and under-advertises context (#6312).
        load = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_mtp_will_engageandnot_draft_cpu_no_embedded" in load
        assert "ifnot_mtp_reserves_gpu:" in load
        assert "mtp_engaged=_mtp_reserves_gpu" in load

    def test_load_model_adopts_env_tensor_split_mode(self):
        # load_model delegates the tensor decision to _effective_tensor_parallel,
        # which flips to tensor only one-directionally: extras set no split mode,
        # none is overridden, and the env selects tensor (an existing tensor plan
        # is never downgraded). Whitespace-stripped to survive formatter wrapping.
        load = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "tensor_parallel=_effective_tensor_parallel(extra_args,tensor_parallel)" in load
        helper = "".join(inspect.getsource(_effective_tensor_parallel).split())
        assert "notresolved" in helper
        assert "parse_split_mode_override(extra_args)isNone" in helper
        assert "_env_split_mode_is_tensor(env)" in helper

    def test_load_model_does_not_emit_env_only_cache_type(self):
        # Cluster C: an env-only (budget) cache type must not be re-emitted as
        # --cache-type flags (that would rewrite an asymmetric K/V env). Emission
        # is guarded by `not _cache_type_from_env`, set when the value came from
        # _env_main_cache_type_for_budget(). Whitespace-stripped for formatter.
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "cache_type_kv=_env_main_cache_type_for_budget()" in compact
        assert "_cache_type_from_env=cache_type_kvisnotNone" in compact
        assert "andnot_cache_type_from_env" in compact

    def test_load_model_clears_inherited_split_mode_on_layer(self):
        # Cluster A: when the final decision is layer split, an inherited
        # non-layer LLAMA_ARG_SPLIT_MODE (and paired LLAMA_ARG_TENSOR_SPLIT) must
        # be popped from the child env so the child cannot run tensor/row/none
        # against Studio's layer budget. Whitespace-stripped for formatter.
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert 'env.get("LLAMA_ARG_SPLIT_MODE")' in compact
        assert '_inherited_sm!="layer"' in compact
        assert 'env.pop("LLAMA_ARG_SPLIT_MODE",None)' in compact
        assert 'env.pop("LLAMA_ARG_TENSOR_SPLIT",None)' in compact

    def test_load_model_clears_quantized_kv_env_for_tensor(self):
        # Cluster B: tensor mode aborts on quantized KV. An inherited quantized
        # LLAMA_ARG_CACHE_TYPE_K/_V must be popped from the child env so it cannot
        # crash the tensor child (and matches the tensor-safe budget).
        # Whitespace-stripped for formatter.
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert '("LLAMA_ARG_CACHE_TYPE_K","LLAMA_ARG_CACHE_TYPE_V")' in compact
        assert "_ct_rawnotinself._TENSOR_PARALLEL_KV_TYPES" in compact
        assert "env.pop(_ct_var,None)" in compact

    def test_load_model_clears_tensor_split_env_in_tensor_mode(self):
        # review run3 #2: Studio owns the tensor split. When it emits no
        # --tensor-split (even split), a stale inherited LLAMA_ARG_TENSOR_SPLIT must
        # be cleared in the TENSOR branch too (not just the layer downgrade), or the
        # child runs a split Studio didn't budget. The else (tensor) branch pops it.
        src = inspect.getsource(LlamaCppBackend.load_model)
        compact = "".join(src.split())
        # appears in both the layer branch and the tensor branch.
        assert compact.count('env.pop("LLAMA_ARG_TENSOR_SPLIT",None)') >= 2

    def test_load_model_layer_compute_buffer_fallback(self):
        # review run3 #4: when GGUF dims are missing the compute-buffer estimate is
        # 0; the layer path must still reserve the flat fallback (tensor buffer >=
        # layer buffer), not fold 0, or it under-reserves at high --parallel.
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "if_compute_buffer_pipeline<=0:" in compact
        # The RHS expression only (no `_compute_buffer_pipeline=` prefix) so the
        # match survives the formatter wrapping it in parens. It's unique within
        # load_model (the other use of this constant is in MiB, no *1024*1024).
        assert "self._TENSOR_PARALLEL_BUFFER_RESERVE_MIB*1024*1024" in compact

    def test_load_model_passes_unsized_mtp_reserve_to_tensor_planner(self):
        # review run3 #1/#5: a weights-only (KV-unsized) MTP reserve must flow into
        # _plan_tensor_parallel as a flat cushion, else its binary search spends the
        # unsized draft KV on context and OOMs.
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "_tp_unsized_mtp_reserve=" in compact
        # Gated on _mtp_reserves_gpu so a CPU-offloaded drafter reserves nothing.
        assert "(_mtp_reserves_gpuand_mtp_kv_unsized)" in compact
        assert "mtp_flat_reserve_bytes=_tp_unsized_mtp_reserve" in compact

    def test_pool_budget_sums_per_gpu_usable(self):
        # Finding #1: the multi-GPU pooled budget must sum each GPU's own usable
        # budget (so an unknown-total GPU gets the free*frac cushion) rather than
        # pooling free and total separately. The fit calls pass the precomputed
        # budget as an absolute (budget_frac=1.0, total_mib=None) so fit and check
        # agree. Whitespace-stripped for formatter.
        compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
        assert "def_pool_budget_mib(subset,frac):" in compact
        assert "sum(max(0.0,_gpu_usable(g,frac))forginsubset)" in compact
        # No revert to the pooled free/total form.
        assert "def_pool_total(" not in compact
        assert "budget_frac=1.0" in compact


# ---------------------------------------------------------------------------
# Regression: the reported Qwen3.6-27B MTP / 24 GB scenario
# ---------------------------------------------------------------------------


def test_qwen36_class_regression_picks_lower_ctx_with_mtp():
    """A 24 GB card that auto-picks a high context without MTP must pick a
    strictly lower one once the MTP draft reserve is accounted for."""
    b = _make_backend()
    b._can_estimate_kv = lambda: True
    b._estimate_kv_cache_bytes = lambda n, _t = None, **_k: (0 if n <= 0 else int(n * 66_000))
    avail_mib = 24_000
    model = int(17.9 * GIB)  # UD-Q4_K_XL weights
    no_mtp = b._fit_context_to_vram(262144, avail_mib, model)
    with_mtp = b._fit_context_to_vram(
        262144,
        avail_mib,
        model,
        mtp_overhead_fn = lambda c: b._estimate_mtp_overhead_bytes(c) or 0,
    )
    assert 0 < with_mtp < no_mtp


def test_mtp_draft_budget_prefers_user_extras_drafter():
    # A user --model-draft in extras is appended last and wins at launch, so the
    # VRAM budget must size it first; then Studio's emitted mtp_draft_path (which
    # overrides LLAMA_ARG_SPEC_DRAFT_MODEL), then the env drafter (load_model is too
    # entangled to drive end-to-end; assert the precedence at the source level).
    # Whitespace-stripped so the check survives any formatter line-wrapping.
    compact = "".join(inspect.getsource(LlamaCppBackend.load_model).split())
    # CLI extras sized first (env={} so the env doesn't pre-empt Studio's drafter).
    assert "_cli_draft_for_budget=_extra_args_mtp_draft_path(extra_args,env={})" in compact
    # Order: CLI extras, then Studio's mtp_draft_path, then the env drafter.
    assert "_cli_draft_for_budgetor_studio_draft_for_budgetor_env_draft_for_budget" in compact
    # The env must not be consulted before Studio's resolved drafter.
    assert "_extra_args_mtp_draft_path(extra_args)ormtp_draft_path" not in compact
