

# ===== FILE: omlx/__init__.py =====

# SPDX-License-Identifier: Apache-2.0
"""
omlx: LLM inference server, optimized for your Mac

This package provides native Apple Silicon GPU acceleration using
Apple's MLX framework and mlx-lm for LLMs.

Features:
- Continuous batching via vLLM-style scheduler
- OpenAI-compatible API server
- Paged KV cache with prefix sharing
- Tiered cache (GPU + paged SSD offloading)
"""

from omlx._version import __version__

_LAZY = {
    "Request": "omlx.request",
    "RequestOutput": "omlx.request",
    "RequestStatus": "omlx.request",
    "SamplingParams": "omlx.request",
    "Scheduler": "omlx.scheduler",
    "SchedulerConfig": "omlx.scheduler",
    "SchedulerOutput": "omlx.scheduler",
    "EngineCore": "omlx.engine_core",
    "AsyncEngineCore": "omlx.engine_core",
    "EngineConfig": "omlx.engine_core",
    "BlockAwarePrefixCache": "omlx.cache.prefix_cache",
    "PagedCacheManager": "omlx.cache.paged_cache",
    "CacheBlock": "omlx.cache.paged_cache",
    "BlockTable": "omlx.cache.paged_cache",
    "PrefixCacheStats": "omlx.cache.stats",
    "PagedCacheStats": "omlx.cache.stats",
    "CacheStats": "omlx.cache.stats",
    "get_registry": "omlx.model_registry",
    "ModelOwnershipError": "omlx.model_registry",
}


def __getattr__(name: str):
    import importlib
    if name in _LAZY:
        mod = importlib.import_module(_LAZY[name])
        attr = "PagedCacheStats" if name == "CacheStats" else name
        val = getattr(mod, attr)
        globals()[name] = val
        return val
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

__all__ = [
    # Request management
    "Request",
    "RequestOutput",
    "RequestStatus",
    "SamplingParams",
    # Scheduler
    "Scheduler",
    "SchedulerConfig",
    "SchedulerOutput",
    # Engine
    "EngineCore",
    "AsyncEngineCore",
    "EngineConfig",
    # Model registry
    "get_registry",
    "ModelOwnershipError",
    # Prefix cache (paged SSD-only)
    "BlockAwarePrefixCache",
    # Paged cache (memory efficiency)
    "PagedCacheManager",
    "CacheBlock",
    "BlockTable",
    "PagedCacheStats",
    "CacheStats",  # Backward compatibility alias
    # Version
    "__version__",
]


# ===== FILE: omlx/_torch_stub.py =====

# SPDX-License-Identifier: Apache-2.0
"""Minimal ``torch`` stub for the DMG bundle.

xgrammar 0.2.3 declares ``torch>=1.10.0`` as a runtime dep, but oMLX never
exercises its torch-backed code paths: bitmasks are allocated as numpy
``int32`` buffers, the C++ binding fills them, and the MLX kernel applies the
mask. The torch dep is load-bearing only at *import time* — module-level code
in ``xgrammar.matcher``, ``xgrammar.testing``, ``xgrammar.contrib.hf`` and
``tvm_ffi.core`` does ``import torch`` plus a handful of attribute lookups.

Real torch is ~500 MB unpacked on macOS arm64 — too heavy to ship in the DMG.
This stub provides just enough of the torch surface for those modules to
finish loading. Code paths that would actually call into torch raise
``RuntimeError`` from the helpers below; oMLX never reaches them.

When a real torch is installed (pip / Homebrew flow) the stub is a no-op:
``install()`` checks ``importlib.util.find_spec('torch')`` first.
"""

from __future__ import annotations

import importlib.machinery
import importlib.metadata
import importlib.util
import logging
import os
import sys
import threading
import types

logger = logging.getLogger(__name__)

# xgrammar / tvm-ffi versions this stub is known to cover.
# This module is the *single source of truth* — packaging/build.py imports
# these constants to keep the DMG install pin in sync with the stub. Update
# both tuples here when bumping; the build script auto-tracks.
#
# Reachable-but-stubbed torch surface to be aware of when upgrading:
#   - ``torch.full``: ``xgrammar.allocate_token_bitmask`` calls it. oMLX
#     never invokes ``allocate_token_bitmask`` (we use the MLX kernel
#     path), but the symbol is re-exported from ``xgrammar.__init__``.
#     Any future caller that touches it will hit ``_unsupported("full")``
#     and sur

# ===== FILE: apps/omlx-mac/Sources/App/AppDelegate.swift =====

// Application delegate: sequences activation policy, menubar, server
// bootstrap, and signal handlers. The main AppView window is a SwiftUI
// `Window` scene declared in oMLXApp.swift — we no longer build it
// manually here.
//
// Boot flow
//   applicationWillFinishLaunching  → setActivationPolicy(.regular)
//                                     (Dock icon shows briefly during launch)
//   applicationDidFinishLaunching   → load AppConfig
//                                     → install NSWindow observers (drive
//                                       the dock-icon toggle)
//                                     → if first run (no settings.json):
//                                         • show Welcome window (wizard
//                                           persists config + spawns server
//                                           only after Start Server)
//                                     else (returning user):
//                                         • resolve PythonRuntime
//                                         • spawn ServerProcess
//                                         • create MenubarController
//                                         • install POSIX SignalHandlers
//                                         • flip to .accessory next tick
//                                           (Dock icon hides; menubar stays)
//   applicationWillTerminate        → await server.stop(timeout: 10)
//
// Dock-icon toggle
//   Any time an in-app NSWindow becomes main → .regular (Dock icon shows).
//   When the last visible app window closes → .accessory (Dock icon hides).
//   Server + menubar are untouched by the toggle.

import AppKit
import SwiftUI

@MainActor
final class AppDelegate: NSObject, NSApplicationDelegate {
    private(set) var server: ServerProcess?
    private var menubar: MenubarController?
    private var controlServer: AppControlServer?
    let services = AppServices()

    private var welcomeController: WelcomeWindowController?
    private var welcomeCloseObserver: NSObjectProtocol?

    /// Set true by `requestQuit()` to permit a real terminate. Cmd-Q / Dock
    /// Quit / "Quit oMLX" from the application menu all route through
    /// `applicationShouldTerminate`, which (when this flag is false) closes
    /// any visible app window instead of terminating — preserving the
    /// menubar status item + the running server. The menubar's own "Quit"
    /// item flips this flag before triggering termination.
    private var explicitQuitRequested: Bool = false

    /// Set true by `hideWindowsAndDropDockIcon()` so the willCloseNotification
    /// observer knows this close was app-initiated (Cmd-Q / Dock Quit) and
    /// should drop the Dock icon. When false, the close came from the user
    /// clicking the red traffic-light button — leave the Dock icon up so
    /// the user can click it to bring the window back.
    private var dropDockIconOnNextClose: Bool = false

    /// Appearance → "Show Dock Icon". While true, every `.accessory` drop is
    /// suppressed so the Dock icon stays up with no window open.
    private var dockIconAlwaysVisible: Bool {
        MenubarMetricPrefs.showDockIcon
    }

    /// Last value of the pref that was acted on, so the chatty
    /// UserDefaults notification only triggers policy work on real flips.
    private var lastAppliedDockIconPref: Bool?

    func requestQuit() {
        explicitQuitRequested = true
        NSApp.terminate(nil)
    }

    /// Cmd-Q / Dock → Quit path: hide every titled window AND set
    /// `.accessory` so the Dock icon vanishes. Server + menubar stay alive.
    func hideWindowsAndDropDockIcon() {
        dropDockIconOnNextClose = true
        var hidAny = false
        for win in NSApp.windows where win.styleMask.contains(.titled) && win.isVisible {
            win.close()
            if win.isVisible { win.orderOut(nil) }
            hidAny = hidAny || !win.isVisible
        }
        // If close() was vetoed and only orderOut hid the window,
        // wil

# ===== FILE: omlx/admin/static/js/alpine.min.js =====

(()=>{var nt=!1,it=!1,W=[],ot=-1;function Ut(e){Rn(e)}function Rn(e){W.includes(e)||W.push(e),Mn()}function Wt(e){let t=W.indexOf(e);t!==-1&&t>ot&&W.splice(t,1)}function Mn(){!it&&!nt&&(nt=!0,queueMicrotask(Nn))}function Nn(){nt=!1,it=!0;for(let e=0;e<W.length;e++)W[e](),ot=e;W.length=0,ot=-1,it=!1}var T,N,$,at,st=!0;function Gt(e){st=!1,e(),st=!0}function Jt(e){T=e.reactive,$=e.release,N=t=>e.effect(t,{scheduler:r=>{st?Ut(r):r()}}),at=e.raw}function ct(e){N=e}function Yt(e){let t=()=>{};return[n=>{let i=N(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),$(i))},i},()=>{t()}]}function ve(e,t){let r=!0,n,i=N(()=>{let o=e();JSON.stringify(o),r?n=o:queueMicrotask(()=>{t(o,n),n=o}),r=!1});return()=>$(i)}var Xt=[],Zt=[],Qt=[];function er(e){Qt.push(e)}function te(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Zt.push(t))}function Ae(e){Xt.push(e)}function Oe(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function lt(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}function tr(e){for(e._x_effects?.forEach(Wt);e._x_cleanups?.length;)e._x_cleanups.pop()()}var ut=new MutationObserver(mt),ft=!1;function ue(){ut.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ft=!0}function dt(){kn(),ut.disconnect(),ft=!1}var le=[];function kn(){let e=ut.takeRecords();le.push(()=>e.length>0&&mt(e));let t=le.length;queueMicrotask(()=>{if(le.length===t)for(;le.length>0;)le.shift()()})}function m(e){if(!ft)return e();dt();let t=e();return ue(),t}var pt=!1,Se=[];function rr(){pt=!0}function nr(){pt=!1,mt(Se),Se=[]}function mt(e){if(pt){Se=Se.concat(e);return}let t=[],r=new Set,n=new Map,i=new Map;for(let o=0;o<e.length;o++)if(!e[o].target._x_ignoreMutationObserver&&(e[o].type==="childList"&&(e[o].removedNodes.forEach(s=>{s.nodeType===1&&s._x_marker&&r.add(s)}),e[o].addedNodes.forEach(s=>{if(s.nodeType===1){if(r.has(s)){r.delete(s);return}s._x_marker||t.push(s)}})),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{lt(s,o)}),n.forEach((o,s)=>{Xt.forEach(a=>a(s,o))});for(let o of r)t.some(s=>s.contains(o))||Zt.forEach(s=>s(o));for(let o of t)o.isConnected&&Qt.forEach(s=>s(o));t=null,r=null,n=null,i=null}function Ce(e){return z(B(e))}function k(e,t,r){return e._x_dataStack=[t,...B(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function B(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?B(e.host):e.parentNode?B(e.parentNode):[]}function z(e){return new Proxy({objects:e},Dn)}var Dn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?Pn:Reflect.get(e.find(n=>Reflect.has(n,t))||{},t,r)},set({objects:e},t,r,n){let i=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],o=Object.getOwnPropertyDescriptor(i,t);return o?.set&&o?.get?o.set.call(n,r)||!0:Reflect.set(i,t,r)}};function Pn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function Te(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&

# ===== FILE: omlx/custom_kernels/bonsai/csrc/bindings.cpp =====

// Copyright © 2026 oMLX contributors
// SPDX-License-Identifier: Apache-2.0

#include <nanobind/nanobind.h>
#include <nanobind/stl/pair.h>
#include <nanobind/stl/variant.h>

#include "bonsai_kernels.h"

namespace nb = nanobind;
using namespace nb::literals;

NB_MODULE(_ext, m) {
    m.doc() = "Native Bonsai 1-bit / 2-bit decode kernels for oMLX";

    // ABI canary — see qwen35_prefill/csrc/bindings.cpp for rationale.
    m.def(
        "abi_probe",
        [](const mlx::core::array& a) { return static_cast<int64_t>(a.size()); },
        "a"_a);

    m.def("is_nax_available", &omlx::bonsai_kernels::is_nax_available);

    m.def(
        "bonsai_q1_affine_qmv",
        &omlx::bonsai_kernels::bonsai_q1_affine_qmv,
        "x"_a, "w"_a, "scales"_a, "biases"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_q2_affine_qmv",
        &omlx::bonsai_kernels::bonsai_q2_affine_qmv,
        "x"_a, "w"_a, "scales"_a, "biases"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_q1_affine_qmv_wide",
        &omlx::bonsai_kernels::bonsai_q1_affine_qmv_wide,
        "x"_a, "w"_a, "scales"_a, "biases"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_q2_affine_qmv_wide",
        &omlx::bonsai_kernels::bonsai_q2_affine_qmv_wide,
        "x"_a, "w"_a, "scales"_a, "biases"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_q1_affine_qmv_sym",
        &omlx::bonsai_kernels::bonsai_q1_affine_qmv_sym,
        "x"_a, "w"_a, "scales"_a, "biases"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_q2_affine_qmv_sym",
        &omlx::bonsai_kernels::bonsai_q2_affine_qmv_sym,
        "x"_a, "w"_a, "scales"_a, "biases"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_q1_affine_qmv_wide_sym",
        &omlx::bonsai_kernels::bonsai_q1_affine_qmv_wide_sym,
        "x"_a, "w"_a, "scales"_a, "biases"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_q2_affine_qmv_wide_sym",
        &omlx::bonsai_kernels::bonsai_q2_affine_qmv_wide_sym,
        "x"_a, "w"_a, "scales"_a, "biases"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_t5_qmv",
        &omlx::bonsai_kernels::bonsai_t5_qmv,
        "x"_a, "w"_a, "scales"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_t5_qmv_wide",
        &omlx::bonsai_kernels::bonsai_t5_qmv_wide,
        "x"_a, "w"_a, "scales"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_t5_qmm",
        &omlx::bonsai_kernels::bonsai_t5_qmm,
        "x"_a, "w"_a, "scales"_a,
        "stream"_a = nb::none());

    m.def(
        "bonsai_spec_decode_verify",
        &omlx::bonsai_kernels::bonsai_spec_decode_verify,
        "draft"_a, "target"_a,
        "stream"_a = nb::none());
}


# ===== FILE: omlx/custom_kernels/bonsai/csrc/bonsai_kernels.cpp =====

// Copyright © 2026 oMLX contributors
// SPDX-License-Identifier: Apache-2.0
//
// Bonsai 1-bit / 2-bit Metal kernel dispatch.
//
// Metal kernel sources live in bonsai_quantized.metal (qmv_fast / qmv_wide)
// and spec_decode.metal, compiled into omlx_bonsai_kernels.metallib by CMake.
// The metallib is loaded lazily on the first dispatch call and cached.
//
// MLX 0.32+ requires Metal dispatch to occur inside Primitive::eval_gpu.
// All public API functions return an unevaluated array whose Primitive drives
// the actual Metal dispatch at eval time.

#include "bonsai_kernels.h"

#include <dlfcn.h>
#include <algorithm>
#include <atomic>
#include <filesystem>
#include <sstream>
#include <string>

#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/metal.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"
#include "mlx/primitives.h"
#include "mlx/utils.h"

namespace omlx::bonsai_kernels {

namespace {

using namespace mlx::core;
using namespace mlx::core::metal;

// ---------------------------------------------------------------------------
// Metallib loader
// ---------------------------------------------------------------------------

constexpr const char* kMetface a clear RuntimeError.
#   - ``torch.tensor`` returns a ``_StubTensor`` whose attribute access
#     raises a stub-identifying RuntimeError. Module-level
#     ``_FULL_MASK = torch.tensor(-1, ...)`` patterns succeed at import
#     time; any subsequent method call (.fill_, .item, ...) fails.
_TARGET_XGRAMMAR_VERSIONS = ("0.2.3",)
_TARGET_TVM_FFI_VERSIONS = ("0.1.11",)

# Serialize install() across threads. Without this, two threads that both
# pass the "torch" in sys.modules check race to build modules and overwrite
# each other's sys.modules['torch'] entry, leaving threads that already
# dereferenced the loser's module with stale references. Reachable today
# from concurrent HTTP handlers that call install() on first xgrammar use.
_INSTALL_LOCK = threading.Lock()
_INSTALLED = False


class _StubTensor:
    """Placeholder for ``torch.Tensor`` (annotations + isinstance checks).

    Any attribute access raises a clear RuntimeError so runtime use of a
    stubbed tensor (e.g. ``some_tensor.fill_(...)``) fails loudly with a
    pointer to the cause, rather than at the AttributeError level with a
    generic ``has no attribute 'fill_'`` message.
    """

    def __getattr__(self, name: str):
        # Let dunder probes (pickle, copy.deepcopy, descriptor lookups,
        # `hasattr` chains in third-party libs) fall through cleanly as
        # AttributeError — that's the documented `__getattr__` contract.
        # Real torch tensors lack many of these probed dunders anyway, so
        # raising AttributeError is the correct, distinguishable signal.
        if name.startswith("__") and name.endswith("__"):
            raise AttributeError(name)
        raise RuntimeError(
            f"_StubTensor.{name} is not implemented: oMLX ships a torch "
            "stub for xgrammar's import-time needs only. Reaching a real "
            "tensor method means a code path that needs real torch was "
            "exercised — install torch via pip/Homebrew or report this as "
            "a bug if the call originated inside oMLX."
        )


class _StubDtype:
    __slots__ = ("_name",)

    def __init__(self, name: str) -> None:
        self._name = name

    def __repr__(self) -> str:
        return f"torch.{self._name}"

    # Some xgrammar/tvm-ffi paths convert dtype to string via ``str(dt)``
    # rather than ``repr(dt)`` (e.g. ``to_cpp_dtype`` strips the "torch."
    # prefix). Match real torch's behaviour where ``str(torch.int32)`` is
    # ``"torch.int32"`` so those paths keep working.
    def __str__(self) -> str:
        return f"torch.{self._name}"


def _stub_tensor_factory(*args, **kwargs) -> _StubTensor:
    """torch.tensor(...) stub: returns a _StubTensor instance.

    Returning a real object (rather than None) means module-globals like
    xgrammar.matcher._FULL_MASK = torch.tensor(-1, dtype=...) succeed at
    import time. Any subsequent method call on the result (.fill_, .item,
    etc.) raises with a clear pointer via _StubTensor.__getattr__.
    """
    return _StubTensor()


def _false(*args, **kwargs) -> bool:
    return False


def _true(*args, **kwargs) -> bool:
    return True


def _zero(*args, **kwargs) -> int:
    return 0


def _unsupported(qualname: str):
    def _fn(*args, **kwargs):
        raise RuntimeError(
            f"torch.{qualname} is not available: this oMLX build ships a "
            "torch stub for xgrammar's import-time needs only. Install "
            "real torch via pip/Homebrew if you need this code path."
        )

    return _fn


# (canonical, alias) pairs — real torch aliases torch.int to torch.int32,
# torch.long to torch.int64, etc.; preserve those identities so code that
# does ``torch.int is torch.int32`` keeps working.
_DTYPE_ALIASES: tuple[tuple[str, tuple[str, ...]], ...] = (
    ("int32", ("int",)),
    ("int16", ("short",)),
    ("int64", ("long",)),
    ("float16", ("half",)),
    ("float32", ("float",)),
    ("float64", ("double",)),
    ("int8", ()),
    ("uint8", ()),
    ("bfloat16", ()),
    ("bool", ()),
)

_TENSOR_ALIASES = (
    "Tensor", "LongTensor", "FloatTelCloseNotification didn't fire — drop policy explicitly.
        let stillVisible = NSApp.windows.contains { $0.styleMask.contains(.titled) && $0.isVisible }
        if !stillVisible, !dockIconAlwaysVisible {
            NSApp.setActivationPolicy(.accessory)
        }
        dropDockIconOnNextClose = false
        _ = hidAny
    }

    /// Bring the main AppView window forward. If SwiftUI hasn't materialised
    /// the NSWindow yet (i.e. nobody opened it since launch), kick the
    /// `omlxapp://main` URL — the Window scene in oMLXApp.swift handles it
    /// via `.handlesExternalEvents(matching: ["main"])`.
    func presentAppView() {
        // Flip to .regular eagerly so the Dock icon shows in lockstep with
        // the window appearing. The `didBecomeMain` observer is a backup
        // for other paths (e.g. Welcome window), but on re-opening a hidden
        // SwiftUI Window the notification doesn't always fire (the existing
        // NSWindow is just ordered front rather than re-created), so we
        // can't rely on it here.
        if NSApp.activationPolicy() != .regular {
            NSApp.setActivationPolicy(.regular)
        }
        NSApp.activate(ignoringOtherApps: true)
        if let main = mainAppViewWindow() {
            // Also apply on every show: the observer fires only on
            // didBecomeMain, which may not run if the window was just
            // reordered without becoming main.
            main.titleVisibility = .hidden
            main.makeKeyAndOrderFront(nil)
            return
        }
        if let url = URL(string: "omlxapp://main") {
            NSWorkspace.shared.open(url)
        }
    }

    /// SwiftUI's `Window(id: "main")` tags its NSWindow with that identifier
    /// (the actual rawValue includes a stable prefix; substring match is
    /// stable across macOS revisions).
    private func mainAppViewWindow() -> NSWindow? {
        NSApp.windows.first { window in
            window.identifier?.rawValue.contains("main") == true
        }
    }

    nonisolated func applicationWillFinishLaunching(_ notification: Notification) {
        // Regular policy until the status item registers; we flip to Accessory
        // after creating the menubar (next runloop tick).
        DispatchQueue.main.async {
            NSApp.setActivationPolicy(.regular)
        }
    }

    func applicationDidFinishLaunching(_ notification: Notification) {
        installWindowObservers()
        // Seed without applying: launch flow (accessory flip / welcome)
        // owns the initial policy; only later real flips act.
        lastAppliedDockIconPref = dockIconAlwaysVisible
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(defaultsDidChange(_:)),
            name: UserDefaults.didChangeNotification,
            object: UserDefaults.standard
        )
        services.updates.setTerminateForUpdate { [weak self] in
            if let self {
                self.requestQuit()
            } else {
                NSApp.terminate(nil)
            }
        }
        services.updates.setPresentUpdateConfirmation { [weak self] in
            self?.presentAppView()
        }
        if !isRunningUnitTests {
            do {
                let cliResult = try ShellEnvWriter.ensureCLIShim()
                handleCLISetupResult(cliResult)
            } catch {
                NSLog("oMLX: CLI shim setup failed — \(error)")
            }
            startControlServer()
        }

        let config = AppConfig.load()
        services.updateConfig(config)

        if AppConfig.hasExistingConfig {
            // Returning user. AppConfig.load() picks the highest-priority
            // file (`~/.omlx/settings.json` first, Library config.json
            // second) and stamps `config.source` so future saves route to
            // the same file. No re-write needed here.
            bootstrapServer(config: config)
            scheduleAccessoryPolicyFlip()
        } else {
            // First run: show the wizard only. Do not create the menubar or
     !(s instanceof Element)&&r(s,c)})};return r(e)}function Re(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>In(n,i),s=>ht(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function In(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function ht(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),ht(e[t[0]],t.slice(1),r)}}var ir={};function y(e,t){ir[e]=t}function fe(e,t){let r=Ln(t);return Object.entries(ir).forEach(([n,i])=>{Object.defineProperty(e,`$${n}`,{get(){return i(t,r)},enumerable:!1})}),e}function Ln(e){let[t,r]=_t(e),n={interceptor:Re,...t};return te(e,r),n}function or(e,t,r,...n){try{return r(...n)}catch(i){re(i,e,t)}}function re(e,t,r=void 0){e=Object.assign(e??{message:"No error message given."},{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message}

${r?'Expression: "'+r+`"

`:""}`,t),setTimeout(()=>{throw e},0)}var Me=!0;function ke(e){let t=Me;Me=!1;let r=e();return Me=t,r}function R(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return sr(...e)}var sr=xt;function ar(e){sr=e}function xt(e,t){let r={};fe(r,e);let n=[r,...B(e)],i=typeof t=="function"?$n(n,t):Fn(n,t,e);return or.bind(null,e,t,i)}function $n(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(z([n,...e]),i);Ne(r,o)}}var gt={};function jn(e,t){if(gt[e])return gt[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e.trim())||/^(let|const)\s/.test(e.trim())?`(async()=>{ ${e} })()`:e,o=(()=>{try{let s=new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`);return Object.defineProperty(s,"name",{value:`[Alpine] ${e}`}),s}catch(s){return re(s,t,e),Promise.resolve()}})();return gt[e]=o,o}function Fn(e,t,r){let n=jn(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=z([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>re(l,r,t));n.finished?(Ne(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Ne(i,l,a,s,r)}).catch(l=>re(l,r,t)).finally(()=>n.result=void 0)}}}function Ne(e,t,r,n,i){if(Me&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Ne(e,s,r,n)).catch(s=>re(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var wt="x-";function C(e=""){return wt+e}function cr(e){wt=e}var De={};function d(e,t){return De[e]=t,{before(r){if(!De[r]){console.warn(String.raw`Cannot find directive \`${r}\`. \`${e}\` will use the default order of execution`);return}let n=G.indexOf(r);G.splice(n>=0?n:G.indexOf("DEFAULT"),0,e)}}}function lr(e){return Object.keys(De).includes(e)}function pe(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=Et(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(dr((o,s)=>n[o]=s)).filter(mr).map(zn(n,r)).sort(Kn).map(o=>Bn(e,o))}function Et(e){return Array.from(e).map(dr()).filter(t=>!mr(t))}var yt=!1,de=new Map,ur=Symbol();function fr(e){yt=!0;let t=Symbol();ur=t,de.set(t,[]);let r=()=>{for(;de.get(t).length;)de.get(t).shift()();de.delete(t)},n=()=>{yt=!1,r()};e(r),n()}function _t(e){let t=[],r=a=>t.push(a),[n,i]=Yt(e);return t.push(i),[{Alpine:K,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:R.bind(R,e)},()=>t.forEach(a=>a())]}function Bn(e,t){let r=()=>{},n=De[t.type]||r,[i,o]=_t(e);Oe(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),yt?de.get(ur).push(n):n())};return s.runCleanups=o,s}var Pe=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),Ie=e=>e;function dr(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=pr.reduce((o,s)=>s(o),{name:t,value:r});return n!==tallibName = "omlx_bonsai_kernels";

std::string binary_dir() {
    static std::string dir = []() {
        Dl_info info;
        if (!dladdr(reinterpret_cast<void*>(&binary_dir), &info)) {
            throw std::runtime_error("bonsai: unable to resolve binary dir.");
        }
        return std::filesystem::path(info.dli_fname).parent_path().string();
    }();
    return dir;
}

MTL::ComputePipelineState* get_bonsai_kernel(
    metal::Device& d,
    const std::string& kernel_name) {
    auto* lib = d.get_library(kMetallibName, binary_dir());
    return d.get_kernel(kernel_name, lib);
}

// ---------------------------------------------------------------------------
// Type string helper
// ---------------------------------------------------------------------------

std::string type_str(Dtype dt) {
    if (dt == float16)  return "float16_t";
    if (dt == bfloat16) return "bfloat16_t";
    if (dt == float32)  return "float";
    std::ostringstream msg;
    msg << "bonsai: unsupported dtype " << dt;
    throw std::invalid_argument(msg.str());
}

// ---------------------------------------------------------------------------
// Contiguity helper (used in public API before Primitive is created)
// ---------------------------------------------------------------------------

array ensure_row_contiguous(const array& x, const Stream& s) {
    if (x.flags().row_contiguous) return x;
    return contiguous(x, /*allow_col_major=*/false, s);
}

// ---------------------------------------------------------------------------
// Kernel name construction
// ---------------------------------------------------------------------------

// affine_qmv_fast_[sym_]<type>_gs_<gs>_b_<bits>_batch_<0|1>
std::string qmv_fast_kname(
    const std::string& type, int group_size, int bits, bool batched,
    bool symmetric = false) {
    return std::string(symmetric ? "affine_qmv_fast_sym_" : "affine_qmv_fast_")
        + type
        + "_gs_" + std::to_string(group_size)
        + "_b_"  + std::to_string(bits)
        + (batched ? "_batch_1" : "_batch_0");
}

// affine_qmv_wide_[sym_]<type>_gs_<gs>_b_<bits>_nv_<nv>_kl_<kl>_batch_<0|1>
std::string qmv_wide_kname(
    const std::string& type, int group_size, int bits,
    int vecs_per_tg, int k_lanes, bool batched,
    bool symmetric = false) {
    return std::string(symmetric ? "affine_qmv_wide_sym_" : "affine_qmv_wide_")
        + type
        + "_gs_" + std::to_string(group_size)
        + "_b_"  + std::to_string(bits)
        + "_nv_" + std::to_string(vecs_per_tg)
        + "_kl_" + std::to_string(k_lanes)
        + (batched ? "_batch_1" : "_batch_0");
}

// ---------------------------------------------------------------------------
// Group size derivation
// ---------------------------------------------------------------------------

// MLX packs quantized weights as uint32 (32/bits values per element).
// Exception: Bonsai 1-bit uses uint8 packing (8 values per byte).
int derive_group_size(const array& w, const array& scales, int bits) {
    // Bonsai 1-bit: 32 values per uint32 (vs stock MLX's 8 per uint8).
    int64_t pack = (bits == 1) ? 32 : (32 / bits);
    int64_t K = static_cast<int64_t>(w.shape(-1)) * pack;
    int64_t n_groups = scales.shape(-1);
    if (n_groups <= 0) return 64;
    return static_cast<int>(K / n_groups);
}

// t5 weight tensor: (N, n_groups * bytes_per_group) uint8.
// bytes_per_group = ceil(group_size / 5): 26 for gs=128, 13 for gs=64.
int derive_t5_group_size(const array& w, const array& scales) {
    int64_t n_groups = scales.shape(-1);
    if (n_groups <= 0)
        throw std::invalid_argument("t5: scales has 0 groups");
    int64_t bpg = w.shape(-1) / n_groups;
    if (bpg == 26) return 128;
    if (bpg == 13) return 64;
    std::ostringstream msg;
    msg << "t5: unrecognised bytes_per_group=" << bpg
        << " (expected 26 for gs=128 or 13 for gs=64)";
    throw std::invalid_argument(msg.str());
}

// ---------------------------------------------------------------------------
// t5 kernel name helpers
// -------------------------------------------------------------nsor", "IntTensor", "ByteTensor",
    "DoubleTensor", "HalfTensor", "BoolTensor", "ShortTensor",
)


# Names that xgrammar / tvm_ffi probe via getattr(torch, name) for
# feature-detection — they catch AttributeError and fall back gracefully.
# Logging WARNING for these floods the log on every model load (one per
# name per process) with diagnostics that aren't actually actionable.
# Demote known-probed names to DEBUG; everything else stays WARNING so
# genuinely-missing attributes surface in operator logs.
_KNOWN_PROBE_NAMES: frozenset[str] = frozenset({
    # Integer dtypes added post-torch-2.0 that tvm_ffi.dtypes enumerates
    "uint16", "uint32", "uint64",
    # FP8 / FP4 dtypes (probed by tvm_ffi.dtypes' dtype-mapping table)
    "float8_e4m3fn", "float8_e4m3fnuz",
    "float8_e5m2", "float8_e5m2fnuz",
    "float8_e8m0fnu",
    "float4_e2m1fn_x2",
})


def _make_top_level_torch_getattr() -> "callable":
    """Return a ``__getattr__`` for the stub's top-level torch module.

    Real-torch users who reach an unset attribute would get an
    ``AttributeError``; consumers that probe with ``hasattr`` rely on that.
    But we *also* want a clearly-identifiable message when downstream
    libraries (transformers, accelerate, etc.) reach for a torch surface
    we never stubbed — so this raises ``AttributeError`` whose message
    pinpoints the omlx stub. ``pkgutil.iter_modules(torch.__path__)`` and
    similar discovery paths see the empty ``__path__`` and short-circuit
    before hitting this.
    """

    _missing_attr_logged: set[str] = set()

    def __getattr__(name: str):  # noqa: N807
        # Surface the miss at WARNING level so a future xgrammar release
        # reaching for a new torch attribute is diagnosable from logs
        # before the AttributeError surfaces in a request handler. Rate-
        # limit per name so repeated probes (e.g. hasattr() under a
        # loop) don't flood the journal — once per name per process is
        # enough to identify the gap. Known-probed dtype names log at
        # DEBUG because xgrammar / tvm_ffi catch the AttributeError and
        # the WARNING is pure noise on every model load.
        if name not in _missing_attr_logged:
            _missing_attr_logged.add(name)
            level = logging.DEBUG if name in _KNOWN_PROBE_NAMES else logging.WARNING
            logger.log(
                level,
                "oMLX torch stub missing attribute: torch.%s "
                "(install real torch if this is load-bearing)",
                name,
            )
        # Dunder probes always fall through as AttributeError so pickling,
        # copy.deepcopy, and similar Python machinery work as expected.
        raise AttributeError(
            f"torch.{name!s} is not provided by the oMLX torch stub. "
            "Install real torch via pip/Homebrew if this attribute is "
            "actually needed."
        )

    return __getattr__


def _build_modules() -> dict[str, types.ModuleType]:
    torch = types.ModuleType("torch")
    for alias in _TENSOR_ALIASES:
        setattr(torch, alias, _StubTensor)
    torch.dtype = _StubDtype
    torch.__version__ = "0.0.0+omlx-stub"
    # Pin the stub as the source of truth for the xgrammar version it
    # targets; packaging/build.py imports this constant to stay in sync.
    # (Module-level constant lives at the top of this file.)
    for canonical, aliases in _DTYPE_ALIASES:
        dt = _StubDtype(canonical)
        setattr(torch, canonical, dt)
        for a in aliases:
            setattr(torch, a, dt)
    torch.tensor = _stub_tensor_factory
    torch.full = _unsupported("full")
    torch.zeros = _unsupported("zeros")
    torch.from_dlpack = _unsupported("from_dlpack")

    cuda = types.ModuleType("torch.cuda")
    cuda.is_available = _false
    cuda.device_count = _zero

    cuda_amp_common = types.ModuleType("torch.cuda.amp.common")
    cuda_amp_common.amp_definitely_not_available = _true
    cuda_amp = types.ModuleType("torch.cuda.amp")
    cuda_amp.common = cuda_amp_common
    cuda.amp = cuda_amp

    class _Stream:
              // persist settings until the user clicks Start Server.
            NSApp.activate(ignoringOtherApps: true)
            presentWelcome()
        }
    }

    private func handleCLISetupResult(_ result: ShellEnvWriter.CLISetupResult) {
        guard case .needsShellPathPrompt(let reason) = result else { return }
        guard !ShellEnvWriter.shouldSuppressCLIPathPrompt() else { return }
        promptForShellPathExport(reason: reason)
    }

    private func promptForShellPathExport(reason: String) {
        let alert = NSAlert()
        alert.messageText = "Enable `omlx` in Terminal?"
        alert.informativeText = """
        oMLX could not create a public `omlx` command in /opt/homebrew/bin or /usr/local/bin.

        To make `omlx` available in new Terminal sessions, oMLX can add a small PATH block to your shell init file. This only happens if you choose Update Shell File.

        \(reason)
        """
        alert.addButton(withTitle: "Update Shell File")
        alert.addButton(withTitle: "Dismiss Now")
        alert.addButton(withTitle: "Don't Ask Again")
        alert.window.level = .floating

        switch alert.runModal() {
        case .alertFirstButtonReturn:
            do {
                try ShellEnvWriter.ensureShellPathExport()
            } catch {
                NSLog("oMLX: CLI shell path setup failed — \(error)")
            }
        case .alertThirdButtonReturn:
            ShellEnvWriter.suppressCLIPathPromptForever()
        default:
            break
        }
    }

    private var isRunningUnitTests: Bool {
        ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil
    }

    /// All three MenubarController construction sites (first-run, returning
    /// user success, returning user failure) capture the same `openAppView`
    /// closure and differ only in `server`/`lastError`.
    private func makeMenubar(
        server: ServerProcess?,
        config: AppConfig,
        lastError: Error? = nil
    ) -> MenubarController {
        MenubarController(
            server: server,
            config: config,
            updates: services.updates,
            lastError: lastError,
            client: services.client,
            openModelSettings: { [weak self] id in
                guard let self else { return }
                self.services.modelDetailID = id
                self.services.requestedSection = .models
                self.presentAppView()
            },
            openAppView: { [weak self] in self?.presentAppView() },
            openAppearanceSettings: { [weak self] in
                guard let self else { return }
                self.services.requestedSection = .appearance
                self.presentAppView()
            },
            requestQuit:  { [weak self] in self?.requestQuit() }
        )
    }

    /// UserDefaults writes can come from any thread; hop before touching
    /// the activation policy.
    @objc nonisolated private func defaultsDidChange(_ note: Notification) {
        Task { @MainActor in
            self.applyDockIconPreference()
        }
    }

    /// Applies a "Show Dock Icon" flip immediately: ON shows the icon right
    /// away; OFF returns to menubar-only unless a window is currently open
    /// (then the regular auto rule takes over on its next close).
    private func applyDockIconPreference() {
        let pref = dockIconAlwaysVisible
        guard pref != lastAppliedDockIconPref else { return }
        lastAppliedDockIconPref = pref

        if pref {
            if NSApp.activationPolicy() != .regular {
                NSApp.setActivationPolicy(.regular)
            }
            return
        }
        let anyVisible = NSApp.windows.contains { $0.isVisible && isAppOwnedWindow($0) }
        if !anyVisible, NSApp.activationPolicy() != .accessory {
            NSApp.setActivationPolicy(.accessory)
        }
    }

    private func bootstrapServer(config: AppConfig) {
        do {
            let runtime = try PythonRuntime.resolve()
            let server = ServerProcess(
                runtime: runtim&&e(n,t),{name:n,value:i}}}var pr=[];function ne(e){pr.push(e)}function mr({name:e}){return hr().test(e)}var hr=()=>new RegExp(`^${wt}([^:^.]+)\\b`);function zn(e,t){return({name:r,value:n})=>{let i=r.match(hr()),o=r.match(/:([a-zA-Z0-9\-_:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var bt="DEFAULT",G=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",bt,"teleport"];function Kn(e,t){let r=G.indexOf(e.type)===-1?bt:e.type,n=G.indexOf(t.type)===-1?bt:t.type;return G.indexOf(r)-G.indexOf(n)}function J(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function D(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>D(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)D(n,t,!1),n=n.nextElementSibling}function E(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var _r=!1;function gr(){_r&&E("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),_r=!0,document.body||E("Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine's `<script>` tag?"),J(document,"alpine:init"),J(document,"alpine:initializing"),ue(),er(t=>S(t,D)),te(t=>P(t)),Ae((t,r)=>{pe(t,r).forEach(n=>n())});let e=t=>!Y(t.parentElement,!0);Array.from(document.querySelectorAll(br().join(","))).filter(e).forEach(t=>{S(t)}),J(document,"alpine:initialized"),setTimeout(()=>{Vn()})}var vt=[],xr=[];function yr(){return vt.map(e=>e())}function br(){return vt.concat(xr).map(e=>e())}function Le(e){vt.push(e)}function $e(e){xr.push(e)}function Y(e,t=!1){return j(e,r=>{if((t?br():yr()).some(i=>r.matches(i)))return!0})}function j(e,t){if(e){if(t(e))return e;if(e._x_teleportBack&&(e=e._x_teleportBack),!!e.parentElement)return j(e.parentElement,t)}}function wr(e){return yr().some(t=>e.matches(t))}var Er=[];function vr(e){Er.push(e)}var Hn=1;function S(e,t=D,r=()=>{}){j(e,n=>n._x_ignore)||fr(()=>{t(e,(n,i)=>{n._x_marker||(r(n,i),Er.forEach(o=>o(n,i)),pe(n,n.attributes).forEach(o=>o()),n._x_ignore||(n._x_marker=Hn++),n._x_ignore&&i())})})}function P(e,t=D){t(e,r=>{tr(r),lt(r),delete r._x_marker})}function Vn(){[["ui","dialog",["[x-dialog], [x-popover]"]],["anchor","anchor",["[x-anchor]"]],["sort","sort",["[x-sort]"]]].forEach(([t,r,n])=>{lr(r)||n.some(i=>{if(document.querySelector(i))return E(`found "${i}", but missing ${t} plugin`),!0})})}var St=[],At=!1;function ie(e=()=>{}){return queueMicrotask(()=>{At||setTimeout(()=>{je()})}),new Promise(t=>{St.push(()=>{e(),t()})})}function je(){for(At=!1;St.length;)St.shift()()}function Sr(){At=!0}function me(e,t){return Array.isArray(t)?Ar(e,t.join(" ")):typeof t=="object"&&t!==null?qn(e,t):typeof t=="function"?me(e,t()):Ar(e,t)}function Ar(e,t){let r=o=>o.split(" ").filter(Boolean),n=o=>o.split(" ").filter(s=>!e.classList.contains(s)).filter(Boolean),i=o=>(e.classList.add(...o),()=>{e.classList.remove(...o)});return t=t===!0?t="":t||"",i(n(t))}function qn(e,t){let r=a=>a.split(" ").filter(Boolean),n=Object.entries(t).flatMap(([a,c])=>c?r(a):!1).filter(Boolean),i=Object.entries(t).flatMap(([a,c])=>c?!1:r(a)).filter(Boolean),o=[],s=[];return i.forEach(a=>{e.classList.contains(a)&&(e.classList.remove(a),s.push(a))}),n.forEach(a=>{e.classList.contains(a)||(e.classList.add(a),o.push(a))}),()=>{s.forEach(a=>e.classList.add(a)),o.forEach(a=>e.classList.remove(a))}}function X(e,t){return typeof t=="object"&&t!==null?Un(e,t):Wn(e,t)}function Un(e,t){let r={};return Object.entries(t).forEach(([n,i])=>{r[n]=e.style[n],n.startsWith("--")||(n=Gn(n)),e.style.setProperty(n,i)}),setTimeout(()=>{e.style.length===0&&e.removeAttribute("style")}),()=>{X(e,r)}}function Wn(e,t){let r=e.getAttribute("style",t);return e.setAttribute("style",t),()=>{e.setAttribute("style",r||"")}}function Gn(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function he(e,t=(--------------

// affine_qmv_fast_t5_<type>_gs_<gs>
std::string qmv_fast_t5_kname(const std::string& type, int group_size) {
    return "affine_qmv_fast_t5_" + type
        + "_gs_" + std::to_string(group_size);
}

// affine_qmv_wide_t5_<type>_gs_<gs>_nv_<nv>_kl_<kl>
std::string qmv_wide_t5_kname(
    const std::string& type, int group_size, int vecs_per_tg, int k_lanes) {
    return "affine_qmv_wide_t5_" + type
        + "_gs_" + std::to_string(group_size)
        + "_nv_" + std::to_string(vecs_per_tg)
        + "_kl_" + std::to_string(k_lanes);
}

// ---------------------------------------------------------------------------
// t5 dispatch functions
// ---------------------------------------------------------------------------

// Buffer layout for t5 kernels: w(0), scales(1), x(2), y(3), K(4), N(5)
// (no biases — t5 is always symmetric)
void dispatch_qmv_fast_t5(
    const array& x,
    const array& w,
    const array& scales,
    array& out,
    int M, int N, int K,
    int group_size,
    metal::Device& d,
    const Stream& s) {

    std::string kname = qmv_fast_t5_kname(type_str(x.dtype()), group_size);

    auto kernel = get_bonsai_kernel(d, kname);
    auto& enc = metal::get_command_encoder(s);
    enc.set_compute_pipeline_state(kernel);

    int c = 0;
    enc.set_input_array(w,      c++);
    enc.set_input_array(scales, c++);
    enc.set_input_array(x,      c++);
    enc.set_output_array(out,   c++);
    enc.set_bytes(K, c++);
    enc.set_bytes(N, c++);

    int bn = 16, bk = 32;
    MTL::Size group_dims(bk, 4, 1);
    MTL::Size grid_dims(M, (N + bn - 1) / bn, 1);
    enc.dispatch_threadgroups(grid_dims, group_dims);
}

void dispatch_qmv_wide_t5(
    const array& x,
    const array& w,
    const array& scales,
    array& out,
    int M, int N, int K,
    int group_size,
    metal::Device& d,
    const Stream& s) {

    int n_tiles = (M + 4) / 5;
    int vecs_per_tg = (M + n_tiles - 1) / n_tiles;
    int k_lanes = 8;
    int num_simdgroups = 4;
    int rows_per_tg = (32 / k_lanes) * num_simdgroups;

    std::string kname = qmv_wide_t5_kname(
        type_str(x.dtype()), group_size, vecs_per_tg, k_lanes);

    auto kernel = get_bonsai_kernel(d, kname);
    auto& enc = metal::get_command_encoder(s);
    enc.set_compute_pipeline_state(kernel);

    int c = 0;
    enc.set_input_array(w,      c++);
    enc.set_input_array(scales, c++);
    enc.set_input_array(x,      c++);
    enc.set_output_array(out,   c++);
    enc.set_bytes(K, c++);
    enc.set_bytes(N, c++);
    enc.set_bytes(M, c++);

    MTL::Size group_dims(32, num_simdgroups, 1);
    MTL::Size grid_dims(
        (M + vecs_per_tg - 1) / vecs_per_tg,
        (N + rows_per_tg - 1) / rows_per_tg,
        1);
    enc.dispatch_threadgroups(grid_dims, group_dims);
}

// ---------------------------------------------------------------------------
// qmv_fast dispatch (called from eval_gpu)
// ---------------------------------------------------------------------------

void dispatch_qmv_fast(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    array& out,
    int M, int N, int K,
    int group_size, int bits,
    metal::Device& d,
    const Stream& s,
    bool symmetric = false) {

    // out shape is x.shape[:-1] + [N], so out.size() == M * N always and
    // the batched kernel variants are never dispatched (not instantiated in
    // the metallib).  Guard the invariant so a future shape change fails
    // loudly here instead of on a missing kernel lookup.
    int B = static_cast<int>(out.size()) / M / N;
    if (B != 1) {
        throw std::runtime_error(
            "[bonsai] batched qmv dispatch is not supported (B=" +
            std::to_string(B) + ")");
    }
    bool batched = false;
    bool fast_aligned = (N % 8 == 0) && (K % 512 == 0);
    // Symmetric fallback: only symmetric fast kernel exists; fall through to
    // affine_qmv (non-fast) for unaligned shapes when symmetric is true, or
    // use the affine path entirely when the shape fails the fast_aligned gate.
    std::string kname = (fast_aligned
         pass

    cuda.Stream = _Stream
    torch.cuda = cuda

    backends_mps = types.ModuleType("torch.backends.mps")
    backends_mps.is_available = _false
    backends_mps.is_built = _false
    backends_cudnn = types.ModuleType("torch.backends.cudnn")
    backends_cudnn.deterministic = False
    backends_cudnn.benchmark = False
    backends = types.ModuleType("torch.backends")
    backends.mps = backends_mps
    backends.cudnn = backends_cudnn
    torch.backends = backends

    version = types.ModuleType("torch.version")
    version.cuda = None
    version.hip = None
    torch.version = version

    nn_functional = types.ModuleType("torch.nn.functional")
    nn_functional.pad = _unsupported("nn.functional.pad")
    nn = types.ModuleType("torch.nn")
    nn.functional = nn_functional
    torch.nn = nn

    utils_dlpack = types.ModuleType("torch.utils.dlpack")
    utils_dlpack.to_dlpack = _unsupported("utils.dlpack.to_dlpack")
    utils = types.ModuleType("torch.utils")
    utils.dlpack = utils_dlpack
    torch.utils = utils

    # Top-level __getattr__ so a future xgrammar that reaches into a
    # torch surface we never stubbed (e.g. ``torch.compile``,
    # ``torch.distributed``) fails with a stub-identifying message rather
    # than a cryptic ``AttributeError: module 'torch' has no attribute…``.
    torch.__getattr__ = _make_top_level_torch_getattr()

    return {
        "torch": torch,
        "torch.cuda": cuda,
        "torch.cuda.amp": cuda_amp,
        "torch.cuda.amp.common": cuda_amp_common,
        "torch.backends": backends,
        "torch.backends.mps": backends_mps,
        "torch.backends.cudnn": backends_cudnn,
        "torch.version": version,
        "torch.nn": nn,
        "torch.nn.functional": nn_functional,
        "torch.utils": utils,
        "torch.utils.dlpack": utils_dlpack,
    }


def install() -> bool:
    """Install the stub into ``sys.modules`` if no real torch is available.

    Returns True if the stub was installed (or had been installed previously),
    False if a real torch was found and left alone.

    Thread-safe — concurrent callers (e.g. multiple FastAPI handlers hitting
    the xgrammar entry points in parallel) serialize on _INSTALL_LOCK.
    """
    global _INSTALLED
    needs_version_check = False
    with _INSTALL_LOCK:
        if _INSTALLED:
            return True

        if "torch" in sys.modules:
            already_stub = getattr(
                sys.modules["torch"], "__version__", ""
            ).endswith("+omlx-stub")
            _INSTALLED = already_stub
            return already_stub

        try:
            if importlib.util.find_spec("torch") is not None:
                # Real torch is on the path — leave it alone, install() is
                # a no-op. Don't mark _INSTALLED so a future sys.modules
                # reset (e.g. in tests) re-evaluates. Crucially, also DO
                # NOT touch ``TVM_FFI_DISABLE_TORCH_C_DLPACK`` — the user
                # has real torch and the tvm-ffi/torch-C-DLPack JIT path
                # may be their preferred fast path.
                return False
        except Exception:
            # find_spec can raise on broken parent packages, partial
            # installs, or weird import hooks. Treat as "no torch" — the
            # stub is the safe fallback.
            pass

        # No real torch — disable tvm_ffi's JIT torch-C-DLPack extension
        # before any tvm-ffi / xgrammar import. Without this,
        # tvm_ffi/_optional_torch_c_dlpack tries to JIT a C extension
        # against our stub at first import, spawns a doomed Python
        # subprocess that fails to ``import torch.utils.cpp_extension``
        # (the stub does not provide it), and surfaces a misleading
        # "Failed to JIT torch c dlpack extension" warning to users on
        # every cold start. The guard inside that module honours this
        # env var and skips the JIT path entirely.
        os.environ.setdefault("TVM_FFI_DISABLE_TORCH_C_DLPACK", "1")

        for name, mod in _build_modules().items():
            # ``__spec__`` must e,
                bindAddress: config.bindAddress,
                port: config.port,
                basePath: URL(fileURLWithPath: config.basePath, isDirectory: true)
            )
            self.server = server
            self.menubar = makeMenubar(server: server, config: config)
            services.bind(server: server)

            // Install signal handlers BEFORE the spawn so a fast crash of
            // the parent during startup still reaps any child we managed
            // to spawn.
            SignalHandlers.shared.install { [weak server] in
                server?.reapSync()
            }

            if config.autoStartOnLaunch {
                switch try server.start() {
                case .started, .alreadyRunning:
                    break
                case .portConflict:
                    // ServerProcess already posted .portConflictNotification +
                    // updated state to .failed; MenubarController will surface
                    // it on next click.
                    break
                }
            }
        } catch {
            // Surface the failure in the menubar header so the user has a
            // recovery affordance without needing to dig through logs.
            self.menubar = makeMenubar(server: nil, config: config, lastError: error)
            NSLog("oMLX: server bootstrap failed — \(error)")
        }
    }

    private func scheduleAccessoryPolicyFlip() {
        // Defer the policy flip so the status item has time to register
        // with WindowServer before we hide the Dock icon (mirrors
        // switchToAccessoryPolicy_ in app.py:324-327).
        DispatchQueue.main.async { [weak self] in
            guard self?.dockIconAlwaysVisible != true else { return }
            NSApp.setActivationPolicy(.accessory)
            NSApp.activate(ignoringOtherApps: true)
        }
    }

    // MARK: - Dock-icon toggle via NSWindow observers

    /// Wire NSWindow lifecycle notifications so the Dock icon follows the
    /// "any app window visible → .regular, none → .accessory" rule.
    /// Both the Welcome wizard and the SwiftUI main window participate; the
    /// menubar status item is not an NSWindow and is unaffected.
    ///
    /// Uses the selector-based observer API (not the closure-based one) so
    /// the non-Sendable Notification + NSWindow values don't need to cross
    /// an actor boundary. NSWindow.* notifications are delivered on the
    /// main thread per Apple's documented contract, so the AppDelegate's
    /// @MainActor methods receive them safely.
    private func installWindowObservers() {
        let center = NotificationCenter.default
        center.addObserver(self,
                           selector: #selector(windowDidBecomeMainNotification(_:)),
                           name: NSWindow.didBecomeMainNotification,
                           object: nil)
        center.addObserver(self,
                           selector: #selector(windowWillCloseNotification(_:)),
                           name: NSWindow.willCloseNotification,
                           object: nil)
    }

    @objc private func windowDidBecomeMainNotification(_ notif: Notification) {
        guard let win = notif.object as? NSWindow, isAppOwnedWindow(win) else { return }
        // Hide the SwiftUI Window scene's title text in the title bar
        // (the "oMLX" floating above the toolbar zone). The title string
        // is still used by the Window menu / Dock-icon right-click menu —
        // only the in-bar display is suppressed. Matches Settings.app's
        // chrome where the title bar is left to the per-screen big title
        // we render inside ContentScaffold.
        if win.identifier?.rawValue.contains("main") == true,
           win.titleVisibility != .hidden {
            win.titleVisibility = .hidden
        }
        if NSApp.activationPolicy() != .regular {
            NSApp.setActivationPolicy(.regular)
        }
    }

    @objc private func windowWillCloseNotification(_ notif: Notification) {
        guard let win = notif.object a)=>{}){let r=!1;return function(){r?t.apply(this,arguments):(r=!0,e.apply(this,arguments))}}d("transition",(e,{value:t,modifiers:r,expression:n},{evaluate:i})=>{typeof n=="function"&&(n=i(n)),n!==!1&&(!n||typeof n=="boolean"?Yn(e,r,t):Jn(e,n,t))});function Jn(e,t,r){Or(e,me,""),{enter:i=>{e._x_transition.enter.during=i},"enter-start":i=>{e._x_transition.enter.start=i},"enter-end":i=>{e._x_transition.enter.end=i},leave:i=>{e._x_transition.leave.during=i},"leave-start":i=>{e._x_transition.leave.start=i},"leave-end":i=>{e._x_transition.leave.end=i}}[r](t)}function Yn(e,t,r){Or(e,X);let n=!t.includes("in")&&!t.includes("out")&&!r,i=n||t.includes("in")||["enter"].includes(r),o=n||t.includes("out")||["leave"].includes(r);t.includes("in")&&!n&&(t=t.filter((g,b)=>b<t.indexOf("out"))),t.includes("out")&&!n&&(t=t.filter((g,b)=>b>t.indexOf("out")));let s=!t.includes("opacity")&&!t.includes("scale"),a=s||t.includes("opacity"),c=s||t.includes("scale"),l=a?0:1,u=c?_e(t,"scale",95)/100:1,p=_e(t,"delay",0)/1e3,h=_e(t,"origin","center"),w="opacity, transform",F=_e(t,"duration",150)/1e3,Ee=_e(t,"duration",75)/1e3,f="cubic-bezier(0.4, 0.0, 0.2, 1)";i&&(e._x_transition.enter.during={transformOrigin:h,transitionDelay:`${p}s`,transitionProperty:w,transitionDuration:`${F}s`,transitionTimingFunction:f},e._x_transition.enter.start={opacity:l,transform:`scale(${u})`},e._x_transition.enter.end={opacity:1,transform:"scale(1)"}),o&&(e._x_transition.leave.during={transformOrigin:h,transitionDelay:`${p}s`,transitionProperty:w,transitionDuration:`${Ee}s`,transitionTimingFunction:f},e._x_transition.leave.start={opacity:1,transform:"scale(1)"},e._x_transition.leave.end={opacity:l,transform:`scale(${u})`})}function Or(e,t,r={}){e._x_transition||(e._x_transition={enter:{during:r,start:r,end:r},leave:{during:r,start:r,end:r},in(n=()=>{},i=()=>{}){Fe(e,t,{during:this.enter.during,start:this.enter.start,end:this.enter.end},n,i)},out(n=()=>{},i=()=>{}){Fe(e,t,{during:this.leave.during,start:this.leave.start,end:this.leave.end},n,i)}})}window.Element.prototype._x_toggleAndCascadeWithTransitions=function(e,t,r,n){let i=document.visibilityState==="visible"?requestAnimationFrame:setTimeout,o=()=>i(r);if(t){e._x_transition&&(e._x_transition.enter||e._x_transition.leave)?e._x_transition.enter&&(Object.entries(e._x_transition.enter.during).length||Object.entries(e._x_transition.enter.start).length||Object.entries(e._x_transition.enter.end).length)?e._x_transition.in(r):o():e._x_transition?e._x_transition.in(r):o();return}e._x_hidePromise=e._x_transition?new Promise((s,a)=>{e._x_transition.out(()=>{},()=>s(n)),e._x_transitioning&&e._x_transitioning.beforeCancel(()=>a({isFromCancelledTransition:!0}))}):Promise.resolve(n),queueMicrotask(()=>{let s=Cr(e);s?(s._x_hideChildren||(s._x_hideChildren=[]),s._x_hideChildren.push(e)):i(()=>{let a=c=>{let l=Promise.all([c._x_hidePromise,...(c._x_hideChildren||[]).map(a)]).then(([u])=>u?.());return delete c._x_hidePromise,delete c._x_hideChildren,l};a(e).catch(c=>{if(!c.isFromCancelledTransition)throw c})})})};function Cr(e){let t=e.parentNode;if(t)return t._x_hidePromise?t:Cr(t)}function Fe(e,t,{during:r,start:n,end:i}={},o=()=>{},s=()=>{}){if(e._x_transitioning&&e._x_transitioning.cancel(),Object.keys(r).length===0&&Object.keys(n).length===0&&Object.keys(i).length===0){o(),s();return}let a,c,l;Xn(e,{start(){a=t(e,n)},during(){c=t(e,r)},before:o,end(){a(),l=t(e,i)},after:s,cleanup(){c(),l()}})}function Xn(e,t){let r,n,i,o=he(()=>{m(()=>{r=!0,n||t.before(),i||(t.end(),je()),t.after(),e.isConnected&&t.cleanup(),delete e._x_transitioning})});e._x_transitioning={beforeCancels:[],beforeCancel(s){this.beforeCancels.push(s)},cancel:he(function(){for(;this.beforeCancels.length;)this.beforeCancels.shift()();o()}),finish:o},m(()=>{t.start(),t.during()}),Sr(),requestAnimationFrame(()=>{if(r)return;let s=Number(getComputedStyle(e).transitionDuration.replace(/,.*/,"").replace("s",""))*1e3,a=Number(getComputedStyle(e).transitionDelay.replace(/,.*/,"").replace("s",""))*1e3;s===0&&(s=Number(getComputedStyle(e).animationDuration.replace("s",""))*1? qmv_fast_kname(type_str(x.dtype()), group_size, bits, batched, symmetric)
        : ("affine_qmv_" + type_str(x.dtype())
            + "_gs_" + std::to_string(group_size)
            + "_b_"  + std::to_string(bits)
            + (batched ? "_batch_1" : "_batch_0")));

    auto kernel = get_bonsai_kernel(d, kname);
    auto& enc = metal::get_command_encoder(s);
    enc.set_compute_pipeline_state(kernel);

    // Buffer layout: w, scales, biases, x, out, K, N
    int c = 0;
    enc.set_input_array(w,      c++);
    enc.set_input_array(scales, c++);
    enc.set_input_array(biases, c++);
    enc.set_input_array(x,      c++);
    enc.set_output_array(out,   c++);
    enc.set_bytes(K, c++);
    enc.set_bytes(N, c++);

    int bn = 16, bk = 32;
    MTL::Size group_dims(bk, 4, 1);
    MTL::Size grid_dims(M, (N + bn - 1) / bn, B);
    enc.dispatch_threadgroups(grid_dims, group_dims);
}

// ---------------------------------------------------------------------------
// qmv_wide dispatch (called from eval_gpu)
// ---------------------------------------------------------------------------

void dispatch_qmv_wide(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    array& out,
    int M, int N, int K,
    int group_size, int bits,
    metal::Device& d,
    const Stream& s,
    bool symmetric = false) {

    // out shape is x.shape[:-1] + [N], so out.size() == M * N always and
    // the batched kernel variants are never dispatched (not instantiated in
    // the metallib).  Guard the invariant so a future shape change fails
    // loudly here instead of on a missing kernel lookup.
    int B = static_cast<int>(out.size()) / M / N;
    if (B != 1) {
        throw std::runtime_error(
            "[bonsai] batched qmv dispatch is not supported (B=" +
            std::to_string(B) + ")");
    }
    bool batched = false;

    // Tile size: ceil(M/ceil(M/5)), capped at 5
    int n_tiles = (M + 4) / 5;
    int vecs_per_tg = (M + n_tiles - 1) / n_tiles;
    // affine mode uses k_lanes=8 (more rows/simdgroup)
    int k_lanes = 8;
    int num_simdgroups = 4;
    int rows_per_tg = (32 / k_lanes) * num_simdgroups;

    std::string kname = qmv_wide_kname(
        type_str(x.dtype()), group_size, bits, vecs_per_tg, k_lanes, batched, symmetric);

    auto kernel = get_bonsai_kernel(d, kname);
    auto& enc = metal::get_command_encoder(s);
    enc.set_compute_pipeline_state(kernel);

    int c = 0;
    enc.set_input_array(w,      c++);
    enc.set_input_array(scales, c++);
    enc.set_input_array(biases, c++);
    enc.set_input_array(x,      c++);
    enc.set_output_array(out,   c++);
    enc.set_bytes(K, c++);
    enc.set_bytes(N, c++);
    enc.set_bytes(M, c++);

    MTL::Size group_dims(32, num_simdgroups, 1);
    MTL::Size grid_dims(
        (M + vecs_per_tg - 1) / vecs_per_tg,
        (N + rows_per_tg - 1) / rows_per_tg,
        B);
    enc.dispatch_threadgroups(grid_dims, group_dims);
}

// ---------------------------------------------------------------------------
// Primitives
// ---------------------------------------------------------------------------

// BonsaiQmvPrimitive: wraps qmv_fast and qmv_wide dispatch.
//   inputs[0] = x  (row-contiguous activations)
//   inputs[1] = w  (packed quantized weights)
//   inputs[2] = scales
//   inputs[3] = biases
class BonsaiQmvPrimitive : public Primitive {
 public:
    BonsaiQmvPrimitive(Stream s, int bits, bool wide, bool symmetric = false)
        : Primitive(s), bits_(bits), wide_(wide), symmetric_(symmetric) {}

 private:
    int bits_;
    bool wide_;
    bool symmetric_;

    void eval_cpu(
        const std::vector<array>& /* inputs */,
        std::vector<array>& /* outputs */) override {
        throw std::runtime_error("BonsaiQmvPrimitive has no CPU path.");
    }

    void eval_gpu(
        const std::vector<array>& inputs,
        std::vector<array>& outputs) override {
        auto& s = stream();
        auto& d = metal::device(s.device);
        auto& out = outputs[0];
        out.set_data(mlx::core::allocator::malloc(out.nbytes()));

      be a real ModuleSpec (not None) so that
            # ``importlib.util.find_spec`` succeeds when called by
            # transformers and other consumers. ``__version__`` is a
            # clearly-fake value so transformers refuses to take the
            # torch-modeling path.
            mod.__spec__ = importlib.machinery.ModuleSpec(name, loader=None)
            mod.__loader__ = None
            if "." not in name:
                mod.__path__ = []  # type: ignore[attr-defined]
            sys.modules[name] = mod
        _INSTALLED = True
        needs_version_check = True

    # Fire the version-drift check OUTSIDE the install lock — it reads
    # distribution metadata from disk and there is no reason to hold up
    # concurrent install() callers behind it. install() is idempotent at
    # this point — _INSTALLED is set and any racing caller short-circuits
    # at the top of the lock.
    if needs_version_check:
        try:
            warn_if_unexpected_versions()
        except Exception:  # pragma: no cover — defensive
            pass
    return True


def warn_if_unexpected_versions() -> None:
    """Log a warning when installed xgrammar / tvm-ffi versions drift past
    the versions this stub was tested against.

    Reads distribution metadata instead of module attributes: xgrammar
    exposes no ``__version__`` (checked on 0.2.3 and 0.2.4), so the old
    ``getattr(xgrammar, "__version__", None)`` probe never fired and the
    drift warning was dead code. Metadata also avoids importing the heavy
    C++ extension just to read a version string. Best-effort: silent when
    a distribution is not installed.
    """
    try:
        v = importlib.metadata.version("xgrammar")
        if v not in _TARGET_XGRAMMAR_VERSIONS:
            logger.warning(
                "xgrammar %s is not in the torch-stub target set %s; "
                "structured output may fail at runtime. Update the stub "
                "or pin xgrammar back.",
                v,
                _TARGET_XGRAMMAR_VERSIONS,
            )
    except Exception:
        pass
    try:
        v = importlib.metadata.version("apache-tvm-ffi")
        if v not in _TARGET_TVM_FFI_VERSIONS:
            logger.warning(
                "apache-tvm-ffi %s is not in the torch-stub target set %s; "
                "structured output may fail at runtime.",
                v,
                _TARGET_TVM_FFI_VERSIONS,
            )
    except Exception:
        pass


# ===== FILE: omlx/_version.py =====

__version__ = "0.5.4rc2"


# ===== FILE: omlx/adapter/__init__.py =====

# SPDX-License-Identifier: Apache-2.0
"""
Adapters for different model formats.

This module provides adapters for parsing different model output formats
such as Harmony (gpt-oss).
"""

from .harmony import HarmonyStreamingParser

__all__ = ["HarmonyStreamingParser"]


# ===== FILE: omlx/adapter/gemma4.py =====

# SPDX-License-Identifier: Apache-2.0
"""Gemma 4 reasoning-channel output parsing and message extraction."""

from __future__ import annotations

import json
import re
from typing import Any

from ..api.utils import _PRESERVE_BOUNDARY_KEY
from ..utils.tokenizer import create_streaming_detokenizer
from .output_parser import OutputParserFinalizeResult, OutputParserTokenResult

_OPEN_MARKER = "<|channel>thought\n"
_OPEN_MARKER_BARE = "<|channel>"
_CLOSE_MARKER = "<channel|>"
_TURN_END_MARKER = "<turn|>"
_TOOL_RESPONSE_OPEN = "<|tool_response>"
_TOOL_RESPONSE_CLOSE = "<tool_response|>"
_THINK_OPEN = "<think>\n"
_THINK_CLOSE = "</think>\n"

_LEADING_THOUGHT_RE = re.compile(
    r"\A\s*(?:(?:<think>.*?</think>|<\|channel>.*?<channel\|>)\s*)+",
    re.DOTALL,
)

# Matches the STRAY bare-token spellings (<|tool_call> and <tool_call|>),
# not the template's well-formed closing form (</tool_call|> with slash).
_PROTOCOL_MARKER_RE = re.compile(r"<\|tool_call>|<tool_call\|>")


def _strip_protocol_markers(text: Any) -> Any:
    """Remove stray <|tool_call> / <tool_call|> tokens from assistant content."""
    if not isinstance(text, str) or not text:
        return text
    return _PROTOCOLs? NSWindow, isAppOwnedWindow(win) else { return }
        let shouldDropDockIcon = dropDockIconOnNextClose
        // The closing window is still in NSApp.windows at notification time;
        // defer the visible-count check so it reflects post-close state.
        DispatchQueue.main.async {
            let stillVisible = NSApp.windows.contains { other in
                other !== win && other.isVisible && self.isAppOwnedWindow(other)
            }
            // Only drop to .accessory when the app initiated the close (Cmd-Q /
            // Dock Quit / Welcome wizard finish). Red-button close keeps the
            // Dock icon up so clicking it can re-open the window via
            // applicationShouldHandleReopen.
            if !stillVisible, shouldDropDockIcon, !self.dockIconAlwaysVisible {
                NSApp.setActivationPolicy(.accessory)
            }
        }
    }

    /// True for windows we own — excludes Sparkle's update windows, panel
    /// chrome from system services, etc. Heuristic: must be titled
    /// (so panel popovers don't count) and not excluded from the windows
    /// menu (so system status windows don't count).
    private func isAppOwnedWindow(_ win: NSWindow) -> Bool {
        guard win.styleMask.contains(.titled) else { return false }
        guard !win.isExcludedFromWindowsMenu else { return false }
        return true
    }

    // MARK: - Welcome wizard

    private func presentWelcome() {
        // First-run only — once `<basePath>/settings.json` exists,
        // `applicationDidFinishLaunching` takes the returning-user path and
        // this is never reached again.
        let controller = WelcomeWindowController(
            services: services,
            server: server,
            didFinish: { [weak self] _, finishedServer in
                // The wizard returns the spawned ServerProcess. Adopt it so
                // applicationWillTerminate can clean up correctly.
                guard let self else { return }
                self.server = finishedServer
                if let proc = finishedServer {
                    SignalHandlers.shared.install { [weak proc] in
                        proc?.reapSync()
                    }
                }
                self.menubar = self.makeMenubar(
                    server: finishedServer,
                    config: self.services.config
                )
            }
        )
        self.welcomeController = controller

        welcomeCloseObserver = NotificationCenter.default.addObserver(
            forName: WelcomeWindowController.willCloseNotification,
            object: nil,
            queue: .main
        ) { [weak self] _ in
            MainActor.assumeIsolated {
                self?.welcomeDidClose()
            }
        }

        controller.show()
    }

    private func welcomeDidClose() {
        if let observer = welcomeCloseObserver {
            NotificationCenter.default.removeObserver(observer)
            welcomeCloseObserver = nil
        }
        welcomeController = nil

        // Close before Start Server is cancellation: no menubar, no settings,
        // no base directory. Quit completely so relaunch shows Welcome again.
        guard server != nil else {
            explicitQuitRequested = true
            NSApp.terminate(nil)
            return
        }

        // The wizard spawned the server itself. Rebuild the menubar with the
        // running server state and switch to menubar-only mode.
        if let server, menubar != nil {
            self.menubar = makeMenubar(server: server, config: services.config)
        }
        scheduleAccessoryPolicyFlip()
    }

    func applicationWillTerminate(_ notification: Notification) {
        // Graceful stop. SIGKILL fallback is inside ServerProcess.stop().
        // We can't await indefinitely here — AppKit will eventually time
        // us out — so we run a short synchronous reap as belt-and-suspenders
        // (SignalHandlers also covers most external-kill paths).
        NotificationCenter.default.removeObserver(self)
        coe3),m(()=>{t.before()}),n=!0,requestAnimationFrame(()=>{r||(m(()=>{t.end()}),je(),setTimeout(e._x_transitioning.finish,s+a),i=!0)})})}function _e(e,t,r){if(e.indexOf(t)===-1)return r;let n=e[e.indexOf(t)+1];if(!n||t==="scale"&&isNaN(n))return r;if(t==="duration"||t==="delay"){let i=n.match(/([0-9]+)ms/);if(i)return i[1]}return t==="origin"&&["top","right","left","center","bottom"].includes(e[e.indexOf(t)+2])?[n,e[e.indexOf(t)+2]].join(" "):n}var I=!1;function A(e,t=()=>{}){return(...r)=>I?t(...r):e(...r)}function Tr(e){return(...t)=>I&&e(...t)}var Rr=[];function H(e){Rr.push(e)}function Mr(e,t){Rr.forEach(r=>r(e,t)),I=!0,kr(()=>{S(t,(r,n)=>{n(r,()=>{})})}),I=!1}var Be=!1;function Nr(e,t){t._x_dataStack||(t._x_dataStack=e._x_dataStack),I=!0,Be=!0,kr(()=>{Zn(t)}),I=!1,Be=!1}function Zn(e){let t=!1;S(e,(n,i)=>{D(n,(o,s)=>{if(t&&wr(o))return s();t=!0,i(o,s)})})}function kr(e){let t=N;ct((r,n)=>{let i=t(r);return $(i),()=>{}}),e(),ct(t)}function ge(e,t,r,n=[]){switch(e._x_bindings||(e._x_bindings=T({})),e._x_bindings[t]=r,t=n.includes("camel")?si(t):t,t){case"value":Qn(e,r);break;case"style":ti(e,r);break;case"class":ei(e,r);break;case"selected":case"checked":ri(e,t,r);break;default:Pr(e,t,r);break}}function Qn(e,t){if(Ot(e))e.attributes.value===void 0&&(e.value=t),window.fromModel&&(typeof t=="boolean"?e.checked=xe(e.value)===t:e.checked=Dr(e.value,t));else if(ze(e))Number.isInteger(t)?e.value=t:!Array.isArray(t)&&typeof t!="boolean"&&![null,void 0].includes(t)?e.value=String(t):Array.isArray(t)?e.checked=t.some(r=>Dr(r,e.value)):e.checked=!!t;else if(e.tagName==="SELECT")oi(e,t);else{if(e.value===t)return;e.value=t===void 0?"":t}}function ei(e,t){e._x_undoAddedClasses&&e._x_undoAddedClasses(),e._x_undoAddedClasses=me(e,t)}function ti(e,t){e._x_undoAddedStyles&&e._x_undoAddedStyles(),e._x_undoAddedStyles=X(e,t)}function ri(e,t,r){Pr(e,t,r),ii(e,t,r)}function Pr(e,t,r){[null,void 0,!1].includes(r)&&ci(t)?e.removeAttribute(t):(Ir(t)&&(r=t),ni(e,t,r))}function ni(e,t,r){e.getAttribute(t)!=r&&e.setAttribute(t,r)}function ii(e,t,r){e[t]!==r&&(e[t]=r)}function oi(e,t){let r=[].concat(t).map(n=>n+"");Array.from(e.options).forEach(n=>{n.selected=r.includes(n.value)})}function si(e){return e.toLowerCase().replace(/-(\w)/g,(t,r)=>r.toUpperCase())}function Dr(e,t){return e==t}function xe(e){return[1,"1","true","on","yes",!0].includes(e)?!0:[0,"0","false","off","no",!1].includes(e)?!1:e?Boolean(e):null}var ai=new Set(["allowfullscreen","async","autofocus","autoplay","checked","controls","default","defer","disabled","formnovalidate","inert","ismap","itemscope","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","selected","shadowrootclonable","shadowrootdelegatesfocus","shadowrootserializable"]);function Ir(e){return ai.has(e)}function ci(e){return!["aria-pressed","aria-checked","aria-expanded","aria-selected"].includes(e)}function Lr(e,t,r){return e._x_bindings&&e._x_bindings[t]!==void 0?e._x_bindings[t]:jr(e,t,r)}function $r(e,t,r,n=!0){if(e._x_bindings&&e._x_bindings[t]!==void 0)return e._x_bindings[t];if(e._x_inlineBindings&&e._x_inlineBindings[t]!==void 0){let i=e._x_inlineBindings[t];return i.extract=n,ke(()=>R(e,i.expression))}return jr(e,t,r)}function jr(e,t,r){let n=e.getAttribute(t);return n===null?typeof r=="function"?r():r:n===""?!0:Ir(t)?!![t,"true"].includes(n):n}function ze(e){return e.type==="checkbox"||e.localName==="ui-checkbox"||e.localName==="ui-switch"}function Ot(e){return e.type==="radio"||e.localName==="ui-radio"}function Ke(e,t){var r;return function(){var n=this,i=arguments,o=function(){r=null,e.apply(n,i)};clearTimeout(r),r=setTimeout(o,t)}}function He(e,t){let r;return function(){let n=this,i=arguments;r||(e.apply(n,i),r=!0,setTimeout(()=>r=!1,t))}}function Ve({get:e,set:t},{get:r,set:n}){let i=!0,o,s,a=N(()=>{let c=e(),l=r();if(i)n(Ct(c)),i=!1;else{let u=JSON.stringify(c),p=JSON.stringify(l);u!==o?n(Ct(c)):u!==p&&t(Ct(l))}o=JSON.stringify(e()),s=JSON.stringify(r())});return()=>{$(a)}}function Ct(e){return typeof e=="object"?JSON.parse(JSON.stringify(e)):e}fu  const auto& x      = inputs[0];
        const auto& w      = inputs[1];
        const auto& scales = inputs[2];
        const auto& biases = inputs[3];

        // Bonsai 1-bit: 32 values per uint32 (vs stock MLX's 8 values per uint8).
        int64_t pack = (bits_ == 1) ? 32 : (32 / bits_);
        int64_t K = static_cast<int64_t>(w.shape(-1)) * pack;
        int N = static_cast<int>(w.shape(-2));
        int M = static_cast<int>(x.size()) / static_cast<int>(K);
        int group_size = derive_group_size(w, scales, bits_);

        if (wide_) {
            dispatch_qmv_wide(x, w, scales, biases, out,
                              M, N, static_cast<int>(K),
                              group_size, bits_, d, s, symmetric_);
        } else {
            dispatch_qmv_fast(x, w, scales, biases, out,
                              M, N, static_cast<int>(K),
                              group_size, bits_, d, s, symmetric_);
        }
    }

    DEFINE_NAME(BonsaiQmvPrimitive)
};

// BonsaiSpecDecodePrimitive: wraps spec_decode_verify kernel.
//   inputs[0] = draft  [B, K] int32
//   inputs[1] = target [B, K+1] int32 (argmax token ids; caller argmaxes logits)
//   outputs[0] = n_accepted [B] int32
//   outputs[1] = committed  [B, K+1] int32
class BonsaiSpecDecodePrimitive : public Primitive {
 public:
    explicit BonsaiSpecDecodePrimitive(Stream s) : Primitive(s) {}

    void eval_cpu(
        const std::vector<array>& /* inputs */,
        std::vector<array>& /* outputs */) override {
        throw std::runtime_error("BonsaiSpecDecodePrimitive has no CPU path.");
    }

    void eval_gpu(
        const std::vector<array>& inputs,
        std::vector<array>& outputs) override {
        auto& s = stream();
        auto& d = metal::device(s.device);

        auto& n_accepted = outputs[0];
        auto& committed  = outputs[1];
        n_accepted.set_data(mlx::core::allocator::malloc(n_accepted.nbytes()));
        committed.set_data(mlx::core::allocator::malloc(committed.nbytes()));

        const auto& draft  = inputs[0];
        const auto& target = inputs[1];

        int B = draft.shape(0);
        int K = draft.shape(1);

        auto kernel = get_bonsai_kernel(d, "spec_decode_verify");
        auto& enc = metal::get_command_encoder(s);
        enc.set_compute_pipeline_state(kernel);

        enc.set_input_array(draft,       0);
        enc.set_input_array(target,      1);
        enc.set_output_array(n_accepted, 2);
        enc.set_output_array(committed,  3);
        enc.set_bytes(K, 4);
        enc.set_bytes(B, 5);

        int tgroup = std::min(B, 256);
        MTL::Size grid_dims(B, 1, 1);
        MTL::Size group_dims(tgroup, 1, 1);
        enc.dispatch_threads(grid_dims, group_dims);
    }

    DEFINE_NAME(BonsaiSpecDecodePrimitive)
};

// BonsaiT5QmvPrimitive: t5 base-3 ternary decode (Identity I-D).
//   inputs[0] = x      (row-contiguous activations)
//   inputs[1] = w      (uint8 t5 weight bytes, (N, n_groups*bytes_per_group))
//   inputs[2] = scales ((N, n_groups) scale per group; no biases)
class BonsaiT5QmvPrimitive : public Primitive {
 public:
    explicit BonsaiT5QmvPrimitive(Stream s, bool wide)
        : Primitive(s), wide_(wide) {}

 private:
    bool wide_;

    void eval_cpu(
        const std::vector<array>& /* inputs */,
        std::vector<array>& /* outputs */) override {
        throw std::runtime_error("BonsaiT5QmvPrimitive has no CPU path.");
    }

    void eval_gpu(
        const std::vector<array>& inputs,
        std::vector<array>& outputs) override {
        auto& s = stream();
        auto& d = metal::device(s.device);
        auto& out = outputs[0];
        out.set_data(mlx::core::allocator::malloc(out.nbytes()));

        const auto& x      = inputs[0];
        const auto& w      = inputs[1];
        const auto& scales = inputs[2];

        int group_size = derive_t5_group_size(w, scales);
        int N          = static_cast<int>(w.shape(-2));
        int n_groups   = static_cast<int>(scales.shape(-1));
        int K          = n_groups * group_size;
        int M          = static_ca_MARKER_RE.sub("", text)


def _try_parse_json(s: str) -> Any:
    """Parse string as JSON if possible, otherwise return as-is."""
    if not isinstance(s, str):
        return s
    s = s.strip()
    if not s or not (s.startswith("{") or s.startswith("[")):
        return s
    try:
        return json.loads(s)
    except (json.JSONDecodeError, ValueError):
        return s


def _strip_thinking(text: Any) -> Any:
    """Remove leading ``<think>...</think>`` or raw ``<|channel>...<channel|>`` spans.

    Gemma 4's multi-turn rule requires that only the final visible answer
    is kept in chat history. Clients such as Open WebUI replay the full
    assistant content (including the rendered ``<think>`` block, or the
    raw protocol form when a client preserves it). Feeding prior thought
    blocks back primes the model to emit malformed channel markers on the
    next turn, which then leak into user-facing output.

    The match is anchored to the start of the message: the rendered thought
    block always precedes the visible answer, so this catches every
    legitimate occurrence while leaving inline mentions (e.g. an assistant
    explaining how ``<think>`` tags work) untouched.
    """
    if not isinstance(text, str) or not text:
        return text
    return _LEADING_THOUGHT_RE.sub("", text, count=1)


def extract_gemma4_messages(
    messages: list[Any],
    max_tool_result_tokens: int | None = None,
    tokenizer: Any | None = None,
    consolidate_system_messages: bool = True,
) -> list[dict]:
    """Convert OpenAI-format messages to Gemma 4 chat-template format.

    The Gemma 4 chat template does not handle ``role=tool`` messages.
    Tool results must instead appear on a model-role turn as a
    ``tool_responses`` list, where each entry is::

        {"name": "<function_name>", "response": <dict_or_scalar>}

    This function:
    - Passes non-tool messages through unchanged.
    - Preserves ``tool_calls`` on assistant turns (template renders them
      as ``<|tool_call>...</tool_call|>``).
    - Folds consecutive ``role=tool`` messages that follow an assistant
      turn into a single ``{"role": "assistant", "tool_responses": [...]}``
      message, resolving function names from the preceding tool_calls by
      ``tool_call_id``.  Falls back to the raw ``tool_call_id`` as the
      name when no match is found.
    - JSON-parses tool result content into a dict/list where possible so
      the template renders structured responses correctly.

    Args:
        messages: OpenAI-format Message objects or dicts.
        max_tool_result_tokens: Maximum token count for tool results
            (truncation applied when tokenizer is provided).
        tokenizer: Tokenizer for optional truncation.
        consolidate_system_messages: When True, preserve the legacy behavior
            of moving all system/developer messages to the leading system
            prompt. Server routes pass False and defer that decision until the
            model chat template can be probed.

    Returns:
        List of dicts ready for ``tokenizer.apply_chat_template``.
    """
    from ..api.utils import (
        _extract_text_from_content_list,
    )  # avoid circular at module level

    processed: list[dict] = []

    # Build index of message objects as plain dicts
    raw: list[dict] = []
    for msg in messages:
        if hasattr(msg, "model_dump"):
            raw.append(msg.model_dump())
        elif isinstance(msg, dict):
            raw.append(dict(msg))
        else:
            raw.append(
                {
                    "role": getattr(msg, "role", "user"),
                    "content": getattr(msg, "content", ""),
                }
            )

    i = 0
    while i < len(raw):
        msg = raw[i]
        role = msg.get("role", "user")

        if role == "developer":
            role = "system"

        if role == "tool":
            # Orphaned tool result with no preceding assistant turn — attach
            # to a synthetic assistant turn with no content.
            tool_call_id = msg.get("tool_call_id", "")
ntrolServer?.stop()
        controlServer = nil

        guard let server else { return }
        let group = DispatchGroup()
        group.enter()
        Task { @MainActor in
            await server.stop(timeout: 8)
            group.leave()
        }
        _ = group.wait(timeout: .now() + 9)
        server.reapSync(timeout: 1)
    }

    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        // Menubar app — never quit on window close.
        false
    }

    /// Intercept terminate so Cmd-Q / Dock → Quit *only* close the window.
    /// The single real-quit path is the menubar status item's "Quit oMLX",
    /// which routes through `requestQuit()` to set the explicit flag.
    ///
    /// Notes:
    /// - We always cancel terminate when the explicit flag isn't set.
    ///   SwiftUI's Window scene appears to dismiss the window before
    ///   `applicationShouldTerminate` runs, so a "no visible windows"
    ///   guard fires when we'd really want to keep cancelling.
    /// - We use `close()`, not `performClose(_:)`. SwiftUI's window has a
    ///   delegate that vetoes `windowShouldClose:` in some cases — `close()`
    ///   bypasses that and reliably hides the window + fires
    ///   `willClose`/`didClose` so the Dock-icon observer drops to
    ///   `.accessory`.
    func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
        if explicitQuitRequested { return .terminateNow }
        // Same close path used by the SwiftUI Cmd-Q command in oMLXApp.swift.
        hideWindowsAndDropDockIcon()
        return .terminateCancel
    }

    private func startControlServer() {
        let control = AppControlServer()
        control.handler = self
        do {
            try control.start()
            self.controlServer = control
        } catch {
            NSLog("oMLX: app-control server failed to start — \(error)")
        }
    }

    /// Dock icon click while no window is visible: bring the main window
    /// back. macOS calls this only when the user clicks the Dock icon of an
    /// already-running app whose windows are all hidden. With our policy
    /// of keeping the Dock icon up after a red-button close, this is the
    /// canonical "re-open" path.
    func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
        if !flag {
            presentAppView()
        }
        return true
    }
}

extension AppDelegate: AppControlHandling {
    func handleAppControl(_ command: AppControlServer.Command) async -> AppControlServer.Response {
        guard let server else {
            return .failure(
                status: "unavailable",
                state: .stopped,
                server: nil,
                message: "Managed server is unavailable. Complete the oMLX first-run setup in the app."
            )
        }

        switch command {
        case .status:
            return .success(status: "ok", state: server.state, server: server)

        case .start:
            do {
                switch try server.start() {
                case .started:
                    return .success(status: "starting", state: server.state, server: server)
                case .alreadyRunning:
                    return .success(status: "running", state: server.state, server: server)
                case .portConflict(let conflict):
                    let pid = conflict.pid.map(String.init) ?? "unknown"
                    return .failure(
                        status: "port_conflict",
                        state: server.state,
                        server: server,
                        message: "Port \(server.port) is in use by PID \(pid)."
                    )
                }
            } catch {
                return .failure(
                    status: "error",
                    state: server.state,
                    server: server,
                    message: String(describing: error)
                )
            }

        case .stop:
            await server.stop()
nction Fr(e){(Array.isArray(e)?e:[e]).forEach(r=>r(K))}var Z={},Br=!1;function zr(e,t){if(Br||(Z=T(Z),Br=!0),t===void 0)return Z[e];Z[e]=t,Te(Z[e]),typeof t=="object"&&t!==null&&t.hasOwnProperty("init")&&typeof t.init=="function"&&Z[e].init()}function Kr(){return Z}var Hr={};function Vr(e,t){let r=typeof t!="function"?()=>t:t;return e instanceof Element?Tt(e,r()):(Hr[e]=r,()=>{})}function qr(e){return Object.entries(Hr).forEach(([t,r])=>{Object.defineProperty(e,t,{get(){return(...n)=>r(...n)}})}),e}function Tt(e,t,r){let n=[];for(;n.length;)n.pop()();let i=Object.entries(t).map(([s,a])=>({name:s,value:a})),o=Et(i);return i=i.map(s=>o.find(a=>a.name===s.name)?{name:`x-bind:${s.name}`,value:`"${s.value}"`}:s),pe(e,i,r).map(s=>{n.push(s.runCleanups),s()}),()=>{for(;n.length;)n.pop()()}}var Ur={};function Wr(e,t){Ur[e]=t}function Gr(e,t){return Object.entries(Ur).forEach(([r,n])=>{Object.defineProperty(e,r,{get(){return(...i)=>n.bind(t)(...i)},enumerable:!1})}),e}var li={get reactive(){return T},get release(){return $},get effect(){return N},get raw(){return at},version:"3.14.8",flushAndStopDeferringMutations:nr,dontAutoEvaluateFunctions:ke,disableEffectScheduling:Gt,startObservingMutations:ue,stopObservingMutations:dt,setReactivityEngine:Jt,onAttributeRemoved:Oe,onAttributesAdded:Ae,closestDataStack:B,skipDuringClone:A,onlyDuringClone:Tr,addRootSelector:Le,addInitSelector:$e,interceptClone:H,addScopeToNode:k,deferMutations:rr,mapAttributes:ne,evaluateLater:x,interceptInit:vr,setEvaluator:ar,mergeProxies:z,extractProp:$r,findClosest:j,onElRemoved:te,closestRoot:Y,destroyTree:P,interceptor:Re,transition:Fe,setStyles:X,mutateDom:m,directive:d,entangle:Ve,throttle:He,debounce:Ke,evaluate:R,initTree:S,nextTick:ie,prefixed:C,prefix:cr,plugin:Fr,magic:y,store:zr,start:gr,clone:Nr,cloneNode:Mr,bound:Lr,$data:Ce,watch:ve,walk:D,data:Wr,bind:Vr},K=li;function Rt(e,t){let r=Object.create(null),n=e.split(",");for(let i=0;i<n.length;i++)r[n[i]]=!0;return t?i=>!!r[i.toLowerCase()]:i=>!!r[i]}var ui="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly";var Ls=Rt(ui+",async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected");var Jr=Object.freeze({}),$s=Object.freeze([]);var fi=Object.prototype.hasOwnProperty,ye=(e,t)=>fi.call(e,t),V=Array.isArray,oe=e=>Yr(e)==="[object Map]";var di=e=>typeof e=="string",qe=e=>typeof e=="symbol",be=e=>e!==null&&typeof e=="object";var pi=Object.prototype.toString,Yr=e=>pi.call(e),Mt=e=>Yr(e).slice(8,-1);var Ue=e=>di(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e;var We=e=>{let t=Object.create(null);return r=>t[r]||(t[r]=e(r))},mi=/-(\w)/g,js=We(e=>e.replace(mi,(t,r)=>r?r.toUpperCase():"")),hi=/\B([A-Z])/g,Fs=We(e=>e.replace(hi,"-$1").toLowerCase()),Nt=We(e=>e.charAt(0).toUpperCase()+e.slice(1)),Bs=We(e=>e?`on${Nt(e)}`:""),kt=(e,t)=>e!==t&&(e===e||t===t);var Dt=new WeakMap,we=[],L,Q=Symbol("iterate"),Pt=Symbol("Map key iterate");function _i(e){return e&&e._isEffect===!0}function rn(e,t=Jr){_i(e)&&(e=e.raw);let r=xi(e,t);return t.lazy||r(),r}function nn(e){e.active&&(on(e),e.options.onStop&&e.options.onStop(),e.active=!1)}var gi=0;function xi(e,t){let r=function(){if(!r.active)return e();if(!we.includes(r)){on(r);try{return bi(),we.push(r),L=r,e()}finally{we.pop(),sn(),L=we[we.length-1]}}};return r.id=gi++,r.allowRecurse=!!t.allowRecurse,r._isEffect=!0,r.active=!0,r.raw=e,r.deps=[],r.options=t,r}function on(e){let{deps:t}=e;if(t.length){for(let r=0;r<t.length;r++)t[r].delete(e);t.length=0}}var se=!0,Lt=[];function yi(){Lt.push(se),se=!1}function bi(){Lt.push(se),se=!0}function sn(){let e=Lt.pop();se=e===void 0?!0:e}function M(e,t,r){if(!se||L===void 0)return;let n=Dt.get(e);n||Dt.set(e,n=new Map);let i=n.get(r);i||n.set(r,i=new Set),i.has(L)||(i.add(L),L.deps.push(i),L.options.onTrack&&L.options.onTrack({effect:L,target:e,type:t,key:r}))}function U(e,t,r,n,i,o){let s=Dt.get(e);if(!s)return;let a=new Set,c=u=>{u&&u.forEach(p=>{(p!==L||p.allowRecurse)&&a.add(p)})};if(t==="clear")s.forEach(c);else if(r==="st<int>(x.size()) / K;

        if (wide_) {
            dispatch_qmv_wide_t5(x, w, scales, out,
                                 M, N, K, group_size, d, s);
        } else {
            dispatch_qmv_fast_t5(x, w, scales, out,
                                 M, N, K, group_size, d, s);
        }
    }

    DEFINE_NAME(BonsaiT5QmvPrimitive)
};

// ---------------------------------------------------------------------------
// BonsaiT5QmmPrimitive: t5 MMA GEMM for prefill (Identity I-M).
//   inputs[0] = x      (M, K) row-contiguous activations
//   inputs[1] = w      (N, n_groups*bpg) uint8 t5 bytes
//   inputs[2] = scales (N, n_groups)
// ---------------------------------------------------------------------------

// affine_qmm_t5_<type>_gs_<gs>
static std::string qmm_t5_kname(const std::string& type, int group_size) {
    return "affine_qmm_t5_" + type + "_gs_" + std::to_string(group_size);
}

static void dispatch_qmm_t5(
    const array& x,
    const array& w,
    const array& scales,
    array& out,
    int M, int N, int K,
    int group_size,
    metal::Device& d,
    const Stream& s) {

    std::string kname = qmm_t5_kname(type_str(x.dtype()), group_size);
    auto kernel = get_bonsai_kernel(d, kname);
    auto& enc   = metal::get_command_encoder(s);
    enc.set_compute_pipeline_state(kernel);

    int c = 0;
    enc.set_input_array(w,      c++);
    enc.set_input_array(scales, c++);
    enc.set_input_array(x,      c++);
    enc.set_output_array(out,   c++);
    enc.set_bytes(M, c++);
    enc.set_bytes(N, c++);
    enc.set_bytes(K, c++);

    // Grid: (ceil(N/32), ceil(M/32))  TG: (32, 4, 1)
    MTL::Size group_dims(32, 4, 1);
    MTL::Size grid_dims((N + 31) / 32, (M + 31) / 32, 1);
    enc.dispatch_threadgroups(grid_dims, group_dims);
}

class BonsaiT5QmmPrimitive : public Primitive {
 public:
    explicit BonsaiT5QmmPrimitive(Stream s) : Primitive(s) {}

 private:
    void eval_cpu(
        const std::vector<array>& /* inputs */,
        std::vector<array>& /* outputs */) override {
        throw std::runtime_error("BonsaiT5QmmPrimitive has no CPU path.");
    }

    void eval_gpu(
        const std::vector<array>& inputs,
        std::vector<array>& outputs) override {
        auto& s  = stream();
        auto& d  = metal::device(s.device);
        auto& out = outputs[0];
        out.set_data(mlx::core::allocator::malloc(out.nbytes()));

        const auto& x      = inputs[0];
        const auto& w      = inputs[1];
        const auto& scales = inputs[2];

        int group_size = derive_t5_group_size(w, scales);
        int N          = static_cast<int>(w.shape(-2));
        int n_groups   = static_cast<int>(scales.shape(-1));
        int K          = n_groups * group_size;
        int M          = static_cast<int>(x.size()) / K;

        dispatch_qmm_t5(x, w, scales, out, M, N, K, group_size, d, s);
    }

    DEFINE_NAME(BonsaiT5QmmPrimitive)
};

} // namespace

// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------

// Helper: ensure scales and biases match x's dtype so the Metal kernel
// (which reads them as T = x's dtype) gets correct data.
static array ensure_dtype(const array& a, Dtype dt, const Stream& s) {
    return (a.dtype() == dt) ? a : astype(a, dt, s);
}

array bonsai_q1_affine_qmv(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    auto bi  = ensure_dtype(biases, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiQmvPrimitive>(s, 1, /*wide=*/false),
        {x_c, w, sc, bi});
}

array bonsai_q2_affine_qmv(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    a            content = msg.get("content", "")
            if isinstance(content, list):
                content = _extract_text_from_content_list(content)
            if max_tool_result_tokens and tokenizer and content:
                from ..api.anthropic_utils import truncate_tool_result

                content = truncate_tool_result(
                    content, max_tool_result_tokens, tokenizer
                )
            response = _try_parse_json(content)
            # Fallback name: use tool_call_id
            processed.append(
                {
                    "role": "assistant",
                    "content": "",
                    "tool_responses": [
                        {"name": tool_call_id or "unknown", "response": response}
                    ],
                    _PRESERVE_BOUNDARY_KEY: True,
                }
            )
            i += 1
            continue

        if role == "assistant":
            # Build a tool_call_id → function_name lookup from this turn's calls.
            tc_id_to_name: dict[str, str] = {}
            tool_calls_raw = msg.get("tool_calls") or []
            for tc in tool_calls_raw:
                if isinstance(tc, dict):
                    tc_id = tc.get("id", "")
                    func_name = (tc.get("function") or {}).get("name", "")
                else:
                    tc_id = getattr(tc, "id", "")
                    func = getattr(tc, "function", None)
                    func_name = getattr(func, "name", "") if func else ""
                if tc_id:
                    tc_id_to_name[tc_id] = func_name

            # Extract content
            content = msg.get("content", "")
            if isinstance(content, list):
                content = _extract_text_from_content_list(content)
            # Per Gemma 4's multi-turn rule, prior thought blocks must not
            # be fed back into the next turn. Strip them before rendering.
            content = _strip_thinking(content)
            content = _strip_protocol_markers(content)

            out_msg: dict = {"role": "assistant", "content": content or ""}

            # Preserve tool_calls for template rendering
            if tool_calls_raw:
                out_calls = []
                for tc in tool_calls_raw:
                    if isinstance(tc, dict):
                        func = tc.get("function") or {}
                        out_calls.append(
                            {
                                "id": tc.get("id", ""),
                                "function": {
                                    "name": func.get("name", ""),
                                    "arguments": _try_parse_json(
                                        func.get("arguments", "{}")
                                    ),
                                },
                            }
                        )
                    else:
                        func = getattr(tc, "function", None)
                        args_str = getattr(func, "arguments", "{}") if func else "{}"
                        out_calls.append(
                            {
                                "id": getattr(tc, "id", ""),
                                "function": {
                                    "name": getattr(func, "name", "") if func else "",
                                    "arguments": _try_parse_json(args_str),
                                },
                            }
                        )
                out_msg["tool_calls"] = out_calls
                out_msg[_PRESERVE_BOUNDARY_KEY] = True

            processed.append(out_msg)
            i += 1

            # Consume any immediately following tool results into a
            # single model turn with tool_responses.
            tool_responses = []
            while i < len(raw) and raw[i].get("role") == "tool":
                tr = raw[i]
                tc_id = tr.get("tool_call_id", "")
                tr_content = tr.get("content", "")
                if isinstance(tr_content, list):
                    tr_content = _extract_t            return .success(
                status: "stopped",
                state: server.state,
                server: server,
                message: "oMLX stopped"
            )

        case .restart:
            await server.stop()
            do {
                switch try server.start() {
                case .started:
                    return .success(status: "starting", state: server.state, server: server)
                case .alreadyRunning:
                    return .success(status: "running", state: server.state, server: server)
                case .portConflict(let conflict):
                    let pid = conflict.pid.map(String.init) ?? "unknown"
                    return .failure(
                        status: "port_conflict",
                        state: server.state,
                        server: server,
                        message: "Port \(server.port) is in use by PID \(pid)."
                    )
                }
            } catch {
                return .failure(
                    status: "error",
                    state: server.state,
                    server: server,
                    message: String(describing: error)
                )
            }
        }
    }
}


# ===== FILE: apps/omlx-mac/Sources/App/oMLXApp.swift =====

// SwiftUI shell. The main AppView is a `Window` scene managed by SwiftUI
// (state restoration, autosave, opt-in lifecycle). AppDelegate stays in
// charge of the menubar + server bootstrap + Welcome wizard.
//
// Window lifecycle
//   • `.defaultLaunchBehavior(.suppressed)` keeps the window from appearing
//     at launch — we're a menubar-first app and the user opens it via the
//     status-item's "Admin Panel" command (or the Welcome wizard on first
//     run, which lives in its own manual NSWindow controller).
//   • `.handlesExternalEvents(matching: ["main"])` lets AppDelegate trigger
//     the window the FIRST time via `NSWorkspace.shared.open(omlxapp://main)`
//     when no NSWindow instance has been created yet. Subsequent shows
//     just `makeKeyAndOrderFront` the cached window.
//   • Dock-icon toggle (regular when visible, accessory when closed) is
//     handled by AppDelegate via NSWindow notification observers — not in
//     this file — so the welcome flow shares the same dock-icon logic.

import SwiftUI

@main
struct OMLXApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate

    var body: some Scene {
        // Empty title string keeps the toolbar zone free of "oMLX" text
        // (SwiftUI macOS 26 renders the Window title in the unified toolbar
        // regardless of NSWindow.titleVisibility). The Window menu / Dock
        // right-click menu show the bundle display name ("oMLX") as a
        // fallback when title is empty, so we don't lose the in-menu name.
        Window("", id: "main") {
            AppView()
                .environment(appDelegate.services)
        }
        .defaultLaunchBehavior(.suppressed)
        .handlesExternalEvents(matching: ["main"])
        .windowResizability(.contentMinSize)
        // Replace the system "Quit oMLX" command (Cmd-Q from the in-app
        // menu). Cmd-Q hides every visible window AND drops the Dock icon
        // — same path as Dock → Quit (`applicationShouldTerminate`). The
        // menubar status item's "Quit oMLX" remains the only path to fully
        // terminate.
        .commands {
            CommandGroup(replacing: .appTermination) {
                Button("Close Window") {
                    appDelegate.hideWindowsAndDropDockIcon()
                }
                .keyboardShortcut("q", modifiers: .command)
            }
        }
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/AppSection.swift =====

// Top-level sections rendered by AppView's settings sidebar. Each case becomes
// one selectable row, with `title` driving the visible label (localized with a
// `defaultValue` fallback so the catalog isn't load-bearing) and `symbol`
// driving the SF Symbol on the row.
//
// Section groupings (Server / Molength"&&V(e))s.forEach((u,p)=>{(p==="length"||p>=n)&&c(u)});else switch(r!==void 0&&c(s.get(r)),t){case"add":V(e)?Ue(r)&&c(s.get("length")):(c(s.get(Q)),oe(e)&&c(s.get(Pt)));break;case"delete":V(e)||(c(s.get(Q)),oe(e)&&c(s.get(Pt)));break;case"set":oe(e)&&c(s.get(Q));break}let l=u=>{u.options.onTrigger&&u.options.onTrigger({effect:u,target:e,key:r,type:t,newValue:n,oldValue:i,oldTarget:o}),u.options.scheduler?u.options.scheduler(u):u()};a.forEach(l)}var wi=Rt("__proto__,__v_isRef,__isVue"),an=new Set(Object.getOwnPropertyNames(Symbol).map(e=>Symbol[e]).filter(qe)),Ei=cn();var vi=cn(!0);var Xr=Si();function Si(){let e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...r){let n=_(this);for(let o=0,s=this.length;o<s;o++)M(n,"get",o+"");let i=n[t](...r);return i===-1||i===!1?n[t](...r.map(_)):i}}),["push","pop","shift","unshift","splice"].forEach(t=>{e[t]=function(...r){yi();let n=_(this)[t].apply(this,r);return sn(),n}}),e}function cn(e=!1,t=!1){return function(n,i,o){if(i==="__v_isReactive")return!e;if(i==="__v_isReadonly")return e;if(i==="__v_raw"&&o===(e?t?Bi:dn:t?Fi:fn).get(n))return n;let s=V(n);if(!e&&s&&ye(Xr,i))return Reflect.get(Xr,i,o);let a=Reflect.get(n,i,o);return(qe(i)?an.has(i):wi(i))||(e||M(n,"get",i),t)?a:It(a)?!s||!Ue(i)?a.value:a:be(a)?e?pn(a):et(a):a}}var Ai=Oi();function Oi(e=!1){return function(r,n,i,o){let s=r[n];if(!e&&(i=_(i),s=_(s),!V(r)&&It(s)&&!It(i)))return s.value=i,!0;let a=V(r)&&Ue(n)?Number(n)<r.length:ye(r,n),c=Reflect.set(r,n,i,o);return r===_(o)&&(a?kt(i,s)&&U(r,"set",n,i,s):U(r,"add",n,i)),c}}function Ci(e,t){let r=ye(e,t),n=e[t],i=Reflect.deleteProperty(e,t);return i&&r&&U(e,"delete",t,void 0,n),i}function Ti(e,t){let r=Reflect.has(e,t);return(!qe(t)||!an.has(t))&&M(e,"has",t),r}function Ri(e){return M(e,"iterate",V(e)?"length":Q),Reflect.ownKeys(e)}var Mi={get:Ei,set:Ai,deleteProperty:Ci,has:Ti,ownKeys:Ri},Ni={get:vi,set(e,t){return console.warn(`Set operation on key "${String(t)}" failed: target is readonly.`,e),!0},deleteProperty(e,t){return console.warn(`Delete operation on key "${String(t)}" failed: target is readonly.`,e),!0}};var $t=e=>be(e)?et(e):e,jt=e=>be(e)?pn(e):e,Ft=e=>e,Qe=e=>Reflect.getPrototypeOf(e);function Ge(e,t,r=!1,n=!1){e=e.__v_raw;let i=_(e),o=_(t);t!==o&&!r&&M(i,"get",t),!r&&M(i,"get",o);let{has:s}=Qe(i),a=n?Ft:r?jt:$t;if(s.call(i,t))return a(e.get(t));if(s.call(i,o))return a(e.get(o));e!==i&&e.get(t)}function Je(e,t=!1){let r=this.__v_raw,n=_(r),i=_(e);return e!==i&&!t&&M(n,"has",e),!t&&M(n,"has",i),e===i?r.has(e):r.has(e)||r.has(i)}function Ye(e,t=!1){return e=e.__v_raw,!t&&M(_(e),"iterate",Q),Reflect.get(e,"size",e)}function Zr(e){e=_(e);let t=_(this);return Qe(t).has.call(t,e)||(t.add(e),U(t,"add",e,e)),this}function Qr(e,t){t=_(t);let r=_(this),{has:n,get:i}=Qe(r),o=n.call(r,e);o?un(r,n,e):(e=_(e),o=n.call(r,e));let s=i.call(r,e);return r.set(e,t),o?kt(t,s)&&U(r,"set",e,t,s):U(r,"add",e,t),this}function en(e){let t=_(this),{has:r,get:n}=Qe(t),i=r.call(t,e);i?un(t,r,e):(e=_(e),i=r.call(t,e));let o=n?n.call(t,e):void 0,s=t.delete(e);return i&&U(t,"delete",e,void 0,o),s}function tn(){let e=_(this),t=e.size!==0,r=oe(e)?new Map(e):new Set(e),n=e.clear();return t&&U(e,"clear",void 0,void 0,r),n}function Xe(e,t){return function(n,i){let o=this,s=o.__v_raw,a=_(s),c=t?Ft:e?jt:$t;return!e&&M(a,"iterate",Q),s.forEach((l,u)=>n.call(i,c(l),c(u),o))}}function Ze(e,t,r){return function(...n){let i=this.__v_raw,o=_(i),s=oe(o),a=e==="entries"||e===Symbol.iterator&&s,c=e==="keys"&&s,l=i[e](...n),u=r?Ft:t?jt:$t;return!t&&M(o,"iterate",c?Pt:Q),{next(){let{value:p,done:h}=l.next();return h?{value:p,done:h}:{value:a?[u(p[0]),u(p[1])]:u(p),done:h}},[Symbol.iterator](){return this}}}}function q(e){return function(...t){{let r=t[0]?`on key "${t[0]}" `:"";console.warn(`${Nt(e)} operation ${r}failed: target is readonly.`,_(this))}return e==="delete"?!1:this}}function ki(){let e={get(o){return Ge(this,o)},get size(){return Ye(this)},has:Je,add:Zr,set:Qr,delete:en,clear:tn,forEach:Xe(!1,!1)},t={get(o){return Ge(this,o,!1,!0)},get size(){return Ye(this)},has:Je,auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    auto bi  = ensure_dtype(biases, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiQmvPrimitive>(s, 2, /*wide=*/false),
        {x_c, w, sc, bi});
}

array bonsai_q1_affine_qmv_wide(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    auto bi  = ensure_dtype(biases, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiQmvPrimitive>(s, 1, /*wide=*/true),
        {x_c, w, sc, bi});
}

array bonsai_q2_affine_qmv_wide(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    auto bi  = ensure_dtype(biases, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiQmvPrimitive>(s, 2, /*wide=*/true),
        {x_c, w, sc, bi});
}

array bonsai_q1_affine_qmv_sym(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    auto bi  = ensure_dtype(biases, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiQmvPrimitive>(s, 1, /*wide=*/false, /*symmetric=*/true),
        {x_c, w, sc, bi});
}

array bonsai_q2_affine_qmv_sym(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    auto bi  = ensure_dtype(biases, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiQmvPrimitive>(s, 2, /*wide=*/false, /*symmetric=*/true),
        {x_c, w, sc, bi});
}

array bonsai_q1_affine_qmv_wide_sym(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    auto bi  = ensure_dtype(biases, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiQmvPrimitive>(s, 1, /*wide=*/true, /*symmetric=*/true),
        {x_c, w, sc, bi});
}

array bonsai_q2_affine_qmv_wide_sym(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    auto bi  = ensure_dtype(biases, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiQmvPrimitive>(s, 2, /*wide=*/true, /*symmetric=*/true),
        {x_c, w, sc, bi});
}

array bonsai_t5_qmv(
    const array& x,
    const array& w,
    const array& scales,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, ext_from_content_list(tr_content)
                if max_tool_result_tokens and tokenizer and tr_content:
                    from ..api.anthropic_utils import truncate_tool_result

                    tr_content = truncate_tool_result(
                        tr_content, max_tool_result_tokens, tokenizer
                    )
                response = _try_parse_json(tr_content)
                name = tc_id_to_name.get(tc_id) or tc_id or "unknown"
                tool_responses.append({"name": name, "response": response})
                i += 1

            if tool_responses:
                # Attach tool_responses to the SAME assistant message that
                # has tool_calls.  The Gemma 4 chat template checks for
                # tool_responses on the current message (lines 261-267)
                # BEFORE falling back to a forward-scan for role='tool'
                # messages (lines 268-302).  Putting them on a separate
                # assistant message causes both paths to miss, producing a
                # corrupt bare <|tool_response> tag and making the model
                # loop on the same tool call.
                out_msg["tool_responses"] = tool_responses
            continue

        # All other roles (user, system)
        # Preserve image_url and input_audio parts for VLM processing
        content = msg.get("content", "")
        if isinstance(content, list):
            from ..api.utils import _extract_multimodal_content_list

            multimodal_parts = _extract_multimodal_content_list(content)
            multimodal_types = {"image_url", "input_audio"}
            has_multimodal = any(
                p.get("type") in multimodal_types for p in multimodal_parts
            )
            if has_multimodal:
                content = multimodal_parts
            else:
                content = _extract_text_from_content_list(content)
        out: dict = {"role": role, "content": content if content is not None else ""}
        processed.append(out)
        i += 1

    # Standard cleanup passes shared with other extractors
    from ..api.utils import (
        _consolidate_system_messages,
        _drop_void_assistant_messages,
        _merge_consecutive_roles,
    )

    cleaned = processed
    if consolidate_system_messages:
        cleaned = _consolidate_system_messages(cleaned)
    cleaned = _drop_void_assistant_messages(cleaned)
    return _merge_consecutive_roles(cleaned)


def _matching_prefix_len(text: str, marker: str) -> int:
    """Return longest suffix of ``text`` that is a prefix of ``marker``."""
    max_len = min(len(text), len(marker) - 1)
    for size in range(max_len, 0, -1):
        if text.endswith(marker[:size]):
            return size
    return 0


class Gemma4OutputParserSession:
    """Suppress Gemma 4 protocol markers and re-emit thought blocks as ``<think>`` tags."""

    def __init__(self, tokenizer: Any, model_path: str | None = None):
        self._tokenizer = tokenizer
        self._buffer = ""
        self._in_thought = False
        self._text_mode = False

        self._detokenizer = create_streaming_detokenizer(tokenizer, model_path)
        if self._detokenizer is not None:
            self._detokenizer.reset()

    def _append_text(
        self,
        stream_parts: list[str],
        visible_parts: list[str],
        text: str,
    ) -> None:
        if not text:
            return
        stream_parts.append(text)
        visible_parts.append(text)

    def _active_markers(self) -> list[str]:
        # Channel open/close are tracked unconditionally so a stray
        # ``<channel|>`` outside a thought block (occasionally emitted in long
        # multi-turn contexts) is absorbed instead of leaking into visible
        # text. ``_OPEN_MARKER_BARE`` is a defensive fallback for malformed
        # opens (e.g. ``<|channel>thought<channel|>`` with no newline, or a
        # bare ``<|channel>`` emitted when the model is confused by polluted
        # history). Tool-call markup is intentionally not tracked here — the
        # downstream ``ToolCallStreamFidels / Benchmark / General) live inline in
// AppView; the visual grouping is purely a layout decision in the shell.

import SwiftUI

enum AppSection: String, Hashable, CaseIterable, Identifiable, Sendable {
    case server, status, appearance, network, performance, logs
    case models, downloads, integrations, quantization
    case throughputBench, accuracyBench, contextBench
    case security, about

    var id: String { rawValue }

    var title: String {
        switch self {
        case .server:
            return String(localized: "sidebar.server",
                          defaultValue: "Server",
                          comment: "Sidebar row label / navigation title for the Server section")
        case .network:
            return String(localized: "sidebar.network",
                          defaultValue: "Network",
                          comment: "Sidebar row label / navigation title for the Network section")
        case .performance:
            return String(localized: "sidebar.performance",
                          defaultValue: "Performance",
                          comment: "Sidebar row label / navigation title for the Performance section")
        case .status:
            return String(localized: "sidebar.status",
                          defaultValue: "Status",
                          comment: "Sidebar row label / navigation title for the Status section")
        case .appearance:
            return String(localized: "sidebar.appearance",
                          defaultValue: "Appearance",
                          comment: "Sidebar row label / navigation title for the Appearance section")
        case .logs:
            return String(localized: "sidebar.logs",
                          defaultValue: "Logs",
                          comment: "Sidebar row label / navigation title for the Logs section")
        case .models:
            return String(localized: "sidebar.models",
                          defaultValue: "Models",
                          comment: "Sidebar row label / navigation title for the Models section")
        case .downloads:
            return String(localized: "sidebar.downloads",
                          defaultValue: "Downloads",
                          comment: "Sidebar row label / navigation title for the Downloads section")
        case .integrations:
            return String(localized: "sidebar.integrations",
                          defaultValue: "Integrations",
                          comment: "Sidebar row label / navigation title for the Integrations section")
        case .quantization:
            return String(localized: "sidebar.quantization",
                          defaultValue: "Quantization",
                          comment: "Sidebar row label / navigation title for the Quantization section")
        case .throughputBench:
            return String(localized: "sidebar.throughputBench",
                          defaultValue: "Throughput",
                          comment: "Sidebar row label / navigation title for the Throughput benchmark section")
        case .accuracyBench:
            return String(localized: "sidebar.accuracyBench",
                          defaultValue: "Accuracy",
                          comment: "Sidebar row label / navigation title for the Accuracy benchmark section")
        case .contextBench:
            return String(localized: "sidebar.contextBench",
                          defaultValue: "Context",
                          comment: "Sidebar row label / navigation title for the Context benchmark section")
        case .security:
            return String(localized: "sidebar.security",
                          defaultValue: "Security",
                          comment: "Sidebar row label / navigation title for the Security section")
        case .about:
            return String(localized: "sidebar.about",
                          defaultValue: "About oMLX",
                          comment: "Sidebar row label / navigation title for the About section")
        }
    }

    var symbol: String {
    dd:Zr,set:Qr,delete:en,clear:tn,forEach:Xe(!1,!0)},r={get(o){return Ge(this,o,!0)},get size(){return Ye(this,!0)},has(o){return Je.call(this,o,!0)},add:q("add"),set:q("set"),delete:q("delete"),clear:q("clear"),forEach:Xe(!0,!1)},n={get(o){return Ge(this,o,!0,!0)},get size(){return Ye(this,!0)},has(o){return Je.call(this,o,!0)},add:q("add"),set:q("set"),delete:q("delete"),clear:q("clear"),forEach:Xe(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=Ze(o,!1,!1),r[o]=Ze(o,!0,!1),t[o]=Ze(o,!1,!0),n[o]=Ze(o,!0,!0)}),[e,r,t,n]}var[Di,Pi,Ii,Li]=ki();function ln(e,t){let r=t?e?Li:Ii:e?Pi:Di;return(n,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(ye(r,i)&&i in n?r:n,i,o)}var $i={get:ln(!1,!1)};var ji={get:ln(!0,!1)};function un(e,t,r){let n=_(r);if(n!==r&&t.call(e,n)){let i=Mt(e);console.warn(`Reactive ${i} contains both the raw and reactive versions of the same object${i==="Map"?" as keys":""}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`)}}var fn=new WeakMap,Fi=new WeakMap,dn=new WeakMap,Bi=new WeakMap;function zi(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Ki(e){return e.__v_skip||!Object.isExtensible(e)?0:zi(Mt(e))}function et(e){return e&&e.__v_isReadonly?e:mn(e,!1,Mi,$i,fn)}function pn(e){return mn(e,!0,Ni,ji,dn)}function mn(e,t,r,n,i){if(!be(e))return console.warn(`value cannot be made reactive: ${String(e)}`),e;if(e.__v_raw&&!(t&&e.__v_isReactive))return e;let o=i.get(e);if(o)return o;let s=Ki(e);if(s===0)return e;let a=new Proxy(e,s===2?n:r);return i.set(e,a),a}function _(e){return e&&_(e.__v_raw)||e}function It(e){return Boolean(e&&e.__v_isRef===!0)}y("nextTick",()=>ie);y("dispatch",e=>J.bind(J,e));y("watch",(e,{evaluateLater:t,cleanup:r})=>(n,i)=>{let o=t(n),a=ve(()=>{let c;return o(l=>c=l),c},i);r(a)});y("store",Kr);y("data",e=>Ce(e));y("root",e=>Y(e));y("refs",e=>(e._x_refs_proxy||(e._x_refs_proxy=z(Hi(e))),e._x_refs_proxy));function Hi(e){let t=[];return j(e,r=>{r._x_refs&&t.push(r._x_refs)}),t}var Bt={};function zt(e){return Bt[e]||(Bt[e]=0),++Bt[e]}function hn(e,t){return j(e,r=>{if(r._x_ids&&r._x_ids[t])return!0})}function _n(e,t){e._x_ids||(e._x_ids={}),e._x_ids[t]||(e._x_ids[t]=zt(t))}y("id",(e,{cleanup:t})=>(r,n=null)=>{let i=`${r}${n?`-${n}`:""}`;return Vi(e,i,t,()=>{let o=hn(e,r),s=o?o._x_ids[r]:zt(r);return n?`${r}-${s}-${n}`:`${r}-${s}`})});H((e,t)=>{e._x_id&&(t._x_id=e._x_id)});function Vi(e,t,r,n){if(e._x_id||(e._x_id={}),e._x_id[t])return e._x_id[t];let i=n();return e._x_id[t]=i,r(()=>{delete e._x_id[t]}),i}y("el",e=>e);gn("Focus","focus","focus");gn("Persist","persist","persist");function gn(e,t,r){y(t,n=>E(`You can't use [$${t}] without first installing the "${e}" plugin here: https://alpinejs.dev/plugins/${r}`,n))}d("modelable",(e,{expression:t},{effect:r,evaluateLater:n,cleanup:i})=>{let o=n(t),s=()=>{let u;return o(p=>u=p),u},a=n(`${t} = __placeholder`),c=u=>a(()=>{},{scope:{__placeholder:u}}),l=s();c(l),queueMicrotask(()=>{if(!e._x_model)return;e._x_removeModelListeners.default();let u=e._x_model.get,p=e._x_model.set,h=Ve({get(){return u()},set(w){p(w)}},{get(){return s()},set(w){c(w)}});i(h)})});d("teleport",(e,{modifiers:t,expression:r},{cleanup:n})=>{e.tagName.toLowerCase()!=="template"&&E("x-teleport can only be used on a <template> tag",e);let i=xn(r),o=e.content.cloneNode(!0).firstElementChild;e._x_teleport=o,o._x_teleportBack=e,e.setAttribute("data-teleport-template",!0),o.setAttribute("data-teleport-target",!0),e._x_forwardEvents&&e._x_forwardEvents.forEach(a=>{o.addEventListener(a,c=>{c.stopPropagation(),e.dispatchEvent(new c.constructor(c.type,c))})}),k(o,{},e);let s=(a,c,l)=>{l.includes("prepend")?c.parentNode.insertBefore(a,c):l.includes("append")?c.parentNode.insertBefore(a,c.nextSibling):c.appendChild(a)};m(()=>{s(o,i,t),A(()=>{S(o)})()}),e._x_teleportPutBack=()=>{let a=xn(r);m(()=>{s(e._x_teleport,a,t)})},n(()=>m(()=>{o.remove(),Px_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiT5QmvPrimitive>(s, /*wide=*/false),
        {x_c, w, sc});
}

array bonsai_t5_qmv_wide(
    const array& x,
    const array& w,
    const array& scales,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiT5QmvPrimitive>(s, /*wide=*/true),
        {x_c, w, sc});
}

array bonsai_t5_qmm(
    const array& x,
    const array& w,
    const array& scales,
    StreamOrDevice s_) {
    auto s   = to_stream(s_);
    auto x_c = ensure_row_contiguous(x, s);
    auto sc  = ensure_dtype(scales, x_c.dtype(), s);
    int N = static_cast<int>(w.shape(-2));
    // Output shape: same as x but last dim replaced with N
    auto out_shape = x_c.shape();
    out_shape.back() = N;
    return array(out_shape, x_c.dtype(),
        std::make_shared<BonsaiT5QmmPrimitive>(s),
        {x_c, w, sc});
}

std::pair<array, array> bonsai_spec_decode_verify(
    const array& draft,
    const array& target,
    StreamOrDevice s_) {
    auto s = to_stream(s_);
    int B = draft.shape(0);
    int K = draft.shape(1);

    if (draft.dtype() != mlx::core::int32 || target.dtype() != mlx::core::int32) {
        throw std::invalid_argument(
            "[bonsai_spec_decode_verify] draft and target must be int32 token ids "
            "(argmax target logits before calling).");
    }
    if (target.ndim() != 2 || target.shape(0) != B || target.shape(1) != K + 1) {
        throw std::invalid_argument(
            "[bonsai_spec_decode_verify] target must have shape [B, K+1].");
    }

    // Sibling outputs must be created through make_arrays so eval_gpu
    // receives both in one outputs vector.
    auto primitive = std::make_shared<BonsaiSpecDecodePrimitive>(s);
    auto outs = array::make_arrays(
        {{B}, {B, K + 1}},
        {mlx::core::int32, mlx::core::int32},
        primitive,
        {draft, target});
    return {outs[0], outs[1]};
}

bool is_nax_available() {
    try {
        auto& d = metal::device(mlx::core::Device::gpu);
        // Require gen >= 18 (gen-17 computes wrong results with NAX qmm/gemm,
        // see Bonsai MLX fork commit 4446b4e6).
        return d.get_architecture_gen() >= 18;
    } catch (...) {
        return false;
    }
}

} // namespace omlx::bonsai_kernels


# ===== FILE: omlx/custom_kernels/glm_moe_dsa/csrc/bindings.cpp =====

#include <nanobind/nanobind.h>
#include <nanobind/stl/optional.h>
#include <nanobind/stl/string.h>
#include <nanobind/stl/variant.h>

#include "dsa_indexer.h"
#include "deepseek_v4_sparse_attention.h"
#include "dspark_gemm.h"
#include "dspark_qmv.h"
#include "exact_block_attention.h"
#include "fused_moe.h"
#include "sparse_mla.h"

namespace nb = nanobind;
using namespace nb::literals;

NB_MODULE(_ext, m) {
  m.doc() = "Native GLM kernels for oMLX";

  // ABI canary: when the extension is built with a nanobind whose ABI tag
  // differs from the one the mlx wheel was built with, the NB_DOMAIN is
  // isolated and every mx.array argument is rejected with "incompatible
  // function arguments" (issue #2139). fast.py calls this probe once at
  // import and disables the native symbols when it fails.
  m.def(
      "abi_probe",
      [](const mlx::core::array& a) {
        return static_cast<int64_t>(a.size());
      },
      "a"_a);

  m.def(
      "dsa_indexer_scores",
      &omlx::glm_kernels::dsa_indexer_scores,
      "queries"_a,
      "keys"_a,
      "weights"_a,
      "causal"_a = true,
      "unused_causal_prefix_topk"_a = 0,
      "skip_causal_future_store"_a = false,
      "causal_q_offset"_a = -1,
      "stream"_a = nb::none());
  m.def(
      "dsa_topk_indices",
      &omlx::glm_kernels::dsa_topk_indices,
      "scores"_a,
      "topk"_a,
lter`` removes it from stream deltas
        # while ``parse_tool_calls`` still sees the raw markers in
        # ``output_text`` for extraction.
        return [
            _OPEN_MARKER,
            _OPEN_MARKER_BARE,
            _CLOSE_MARKER,
            _TURN_END_MARKER,
            _TOOL_RESPONSE_OPEN,
            _TOOL_RESPONSE_CLOSE,
        ]

    @staticmethod
    def _find_next_marker(
        source: str, pos: int, markers: list[str]
    ) -> tuple[int, str] | tuple[None, None]:
        next_idx: int | None = None
        next_marker: str | None = None
        for marker in markers:
            idx = source.find(marker, pos)
            if idx == -1:
                continue
            if next_idx is None or idx < next_idx:
                next_idx = idx
                next_marker = marker
        return next_idx, next_marker

    def _consume_text(
        self, text: str, *, final: bool = False
    ) -> OutputParserTokenResult:
        source = self._buffer + text
        self._buffer = ""

        stream_parts: list[str] = []
        visible_parts: list[str] = []
        pos = 0

        while pos < len(source):
            markers = self._active_markers()
            idx, marker = self._find_next_marker(source, pos, markers)

            if idx is None or marker is None:
                remainder = source[pos:]
                if not final:
                    keep = max(
                        _matching_prefix_len(remainder, marker_text)
                        for marker_text in markers
                    )
                    if keep:
                        emit = remainder[:-keep]
                        self._buffer = remainder[-keep:]
                    else:
                        emit = remainder
                else:
                    emit = remainder

                self._append_text(stream_parts, visible_parts, emit)
                break

            # Streaming defer: a bare ``<|channel>`` (or ``<|channel>thought``
            # without trailing newline) at the end of the source could still
            # extend to the canonical ``<|channel>thought\n`` once more
            # tokens arrive. Buffer and wait so the canonical match wins.
            if not final and marker == _OPEN_MARKER_BARE:
                suffix = source[idx:]
                if len(suffix) < len(_OPEN_MARKER) and _OPEN_MARKER.startswith(suffix):
                    self._append_text(stream_parts, visible_parts, source[pos:idx])
                    self._buffer = suffix
                    return OutputParserTokenResult(
                        stream_text="".join(stream_parts),
                        visible_text="".join(visible_parts),
                    )

            self._append_text(stream_parts, visible_parts, source[pos:idx])

            advance = len(marker)

            if marker == _OPEN_MARKER:
                # Nested open while already in a thought block: drop the stray
                # marker without re-emitting ``<think>`` to keep the structure
                # well-formed.
                if not self._in_thought:
                    stream_parts.append(_THINK_OPEN)
                    visible_parts.append(_THINK_OPEN)
                    self._in_thought = True
            elif marker == _OPEN_MARKER_BARE:
                # Defensive fallback for malformed opens: ``<|channel>thought``
                # without the trailing newline, or a bare ``<|channel>`` with
                # an unrecognised channel name. Treat as a thought open and
                # absorb the optional ``thought`` keyword and newline so they
                # don't leak as visible text.
                if not self._in_thought:
                    stream_parts.append(_THINK_OPEN)
                    visible_parts.append(_THINK_OPEN)
                    self._in_thought = True
                after = idx + advance
                if source.startswith("thought\n", after):
                    advance += len("thought\n")
                elif source.startswith("thought", after):
                    advance += len("thought")
        switch self {
        case .server:          return "server.rack"
        case .network:         return "network"
        case .performance:     return "bolt.fill"
        case .status:          return "gauge.with.dots.needle.50percent"
        case .appearance:      return "paintbrush"
        case .logs:            return "scroll"
        case .models:          return "cube.transparent"
        case .downloads:       return "icloud.and.arrow.down"
        case .integrations:    return "powerplug"
        case .quantization:    return "sparkles"
        case .throughputBench: return "speedometer"
        case .accuracyBench:   return "target"
        case .contextBench:    return "ruler"
        case .security:        return "lock"
        case .about:           return "info.circle"
        }
    }

    /// True when the screen wants to fill the content area vertically rather
    /// than ride inside the default outer scroll view. The Logs pane uses
    /// this so its monospace text block grows with the window.
    var fillsContentArea: Bool {
        switch self {
        case .logs: return true
        default:    return false
        }
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/AppServices.swift =====

// PR 7 — wires AppDelegate-owned runtime objects (ServerProcess, AppConfig)
// to the SwiftUI side. AppView mounts a single instance via `.environment`
// so screens can pull whatever they need without prop drilling. The screens
// keep their own data + polling state in their own view models.
//
// `serverState` republishes ServerProcess.State on every state change so a
// view can `@Environment(AppServices.self)` AppServices and use it as a SwiftUI source
// of truth. ServerProcess itself stays NSNotification-driven (no Combine
// retrofit).

import Foundation
import SwiftUI

@MainActor
@Observable
final class AppServices: NSObject {
    var config: AppConfig
    var serverState: ServerProcess.State = .stopped
    /// PR 8 — when non-nil, the AppView swaps the Models screen for the
    /// per-model ModelSettingsScreen drilled to this id.
    var modelDetailID: String?
    /// When set, AppView pulls the sidebar selection to this section on
    /// the next runloop tick and clears the request. Lets a screen
    /// imperatively navigate the user (e.g. the Profiles tab's
    /// "Edit on Server →" link) without prop-drilling a `Binding<AppSection>`.
    var requestedSection: AppSection?
    /// Pair with `requestedSection` to scroll the Server screen to a
    /// specific section after the deep-link lands. ContentScaffold's
    /// `ScrollViewReader` observes this, scrolls, then nils it. Only the
    /// Default Profile anchor is wired today — extend the enum as more
    /// deep links land.
    var requestedServerAnchor: ServerAnchor?

    let client: OMLXClient
    let updates: UpdateController
    /// Read-only preset bundle (sourced from the shipped JSON + remote
    /// refresh). The per-model settings preset chip strip subscribes via
    /// Observation to react to refreshes.
    let presetBundle = PresetBundleStore()

    /// Long-lived view models for the Bench screens. Owned here (not by
    /// screen-local state) so a running benchmark survives
    /// leaving the screen — the server keeps producing results while
    /// we're off-screen and the poll task continues updating these VMs,
    /// so coming back shows the in-flight state instead of an empty
    /// form. The HTML admin panel got this for free via Alpine's
    /// app-scoped store; SwiftUI needs the lifetime promoted manually.
    let throughputBench = ThroughputBenchScreenVM()
    let accuracyBench   = AccuracyBenchScreenVM()
    let contextBench    = ContextBenchScreenVM()

    @ObservationIgnored
    private weak var server: ServerProcess?

    init(config: AppConfig = .default, server: ServerProcess? = nil) {
        self.config = config
        self.client = OMLXClient(host: config.host, port: config.port, apiKey: config.apiKey)
        self.updates = UpdateController()
        super.init()
        self.bind(server: server)
 (o)}))});var qi=document.createElement("div");function xn(e){let t=A(()=>document.querySelector(e),()=>qi)();return t||E(`Cannot find x-teleport element for selector: "${e}"`),t}var yn=()=>{};yn.inline=(e,{modifiers:t},{cleanup:r})=>{t.includes("self")?e._x_ignoreSelf=!0:e._x_ignore=!0,r(()=>{t.includes("self")?delete e._x_ignoreSelf:delete e._x_ignore})};d("ignore",yn);d("effect",A((e,{expression:t},{effect:r})=>{r(x(e,t))}));function ae(e,t,r,n){let i=e,o=c=>n(c),s={},a=(c,l)=>u=>l(c,u);if(r.includes("dot")&&(t=Ui(t)),r.includes("camel")&&(t=Wi(t)),r.includes("passive")&&(s.passive=!0),r.includes("capture")&&(s.capture=!0),r.includes("window")&&(i=window),r.includes("document")&&(i=document),r.includes("debounce")){let c=r[r.indexOf("debounce")+1]||"invalid-wait",l=tt(c.split("ms")[0])?Number(c.split("ms")[0]):250;o=Ke(o,l)}if(r.includes("throttle")){let c=r[r.indexOf("throttle")+1]||"invalid-wait",l=tt(c.split("ms")[0])?Number(c.split("ms")[0]):250;o=He(o,l)}return r.includes("prevent")&&(o=a(o,(c,l)=>{l.preventDefault(),c(l)})),r.includes("stop")&&(o=a(o,(c,l)=>{l.stopPropagation(),c(l)})),r.includes("once")&&(o=a(o,(c,l)=>{c(l),i.removeEventListener(t,o,s)})),(r.includes("away")||r.includes("outside"))&&(i=document,o=a(o,(c,l)=>{e.contains(l.target)||l.target.isConnected!==!1&&(e.offsetWidth<1&&e.offsetHeight<1||e._x_isShown!==!1&&c(l))})),r.includes("self")&&(o=a(o,(c,l)=>{l.target===e&&c(l)})),(Ji(t)||wn(t))&&(o=a(o,(c,l)=>{Yi(l,r)||c(l)})),i.addEventListener(t,o,s),()=>{i.removeEventListener(t,o,s)}}function Ui(e){return e.replace(/-/g,".")}function Wi(e){return e.toLowerCase().replace(/-(\w)/g,(t,r)=>r.toUpperCase())}function tt(e){return!Array.isArray(e)&&!isNaN(e)}function Gi(e){return[" ","_"].includes(e)?e:e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[_\s]/,"-").toLowerCase()}function Ji(e){return["keydown","keyup"].includes(e)}function wn(e){return["contextmenu","click","mouse"].some(t=>e.includes(t))}function Yi(e,t){let r=t.filter(o=>!["window","document","prevent","stop","once","capture","self","away","outside","passive"].includes(o));if(r.includes("debounce")){let o=r.indexOf("debounce");r.splice(o,tt((r[o+1]||"invalid-wait").split("ms")[0])?2:1)}if(r.includes("throttle")){let o=r.indexOf("throttle");r.splice(o,tt((r[o+1]||"invalid-wait").split("ms")[0])?2:1)}if(r.length===0||r.length===1&&bn(e.key).includes(r[0]))return!1;let i=["ctrl","shift","alt","meta","cmd","super"].filter(o=>r.includes(o));return r=r.filter(o=>!i.includes(o)),!(i.length>0&&i.filter(s=>((s==="cmd"||s==="super")&&(s="meta"),e[`${s}Key`])).length===i.length&&(wn(e.type)||bn(e.key).includes(r[0])))}function bn(e){if(!e)return[];e=Gi(e);let t={ctrl:"control",slash:"/",space:" ",spacebar:" ",cmd:"meta",esc:"escape",up:"arrow-up",down:"arrow-down",left:"arrow-left",right:"arrow-right",period:".",comma:",",equal:"=",minus:"-",underscore:"_"};return t[e]=e,Object.keys(t).map(r=>{if(t[r]===e)return r}).filter(r=>r)}d("model",(e,{modifiers:t,expression:r},{effect:n,cleanup:i})=>{let o=e;t.includes("parent")&&(o=e.parentNode);let s=x(o,r),a;typeof r=="string"?a=x(o,`${r} = __placeholder`):typeof r=="function"&&typeof r()=="string"?a=x(o,`${r()} = __placeholder`):a=()=>{};let c=()=>{let h;return s(w=>h=w),En(h)?h.get():h},l=h=>{let w;s(F=>w=F),En(w)?w.set(h):a(()=>{},{scope:{__placeholder:h}})};typeof r=="string"&&e.type==="radio"&&m(()=>{e.hasAttribute("name")||e.setAttribute("name",r)});var u=e.tagName.toLowerCase()==="select"||["checkbox","radio"].includes(e.type)||t.includes("lazy")?"change":"input";let p=I?()=>{}:ae(e,u,t,h=>{l(Kt(e,t,h,c()))});if(t.includes("fill")&&([void 0,null,""].includes(c())||ze(e)&&Array.isArray(c())||e.tagName.toLowerCase()==="select"&&e.multiple)&&l(Kt(e,t,{target:e},c())),e._x_removeModelListeners||(e._x_removeModelListeners={}),e._x_removeModelListeners.default=p,i(()=>e._x_removeModelListeners.default()),e.form){let h=ae(e.form,"reset",[],w=>{ie(()=>e._x_model&&e._x_model.set(Kt(e,t,{target:e},c())))});i(()=>h())}e._x_model={get(){return c()},set(h){l(h)}},e._x_forceModelUpdate=h=>{h===void 0&&typeof r=="st      "bucketed"_a = false,
      "causal_valid_prefix"_a = false,
      "stream"_a = nb::none());
  m.def(
      "dspark_fp32_topk_indices",
      &omlx::glm_kernels::dspark_fp32_topk_indices,
      "scores"_a,
      "topk"_a = 512,
      "stream"_a = nb::none());
  m.def(
      "dsa_decode_scores",
      &omlx::glm_kernels::dsa_decode_scores,
      "queries"_a,
      "keys"_a,
      "weights"_a,
      "fp32_scores"_a = false,
      "stream"_a = nb::none());

  m.def(
      "glm_dsa_sparse_mla_attention",
      &omlx::glm_kernels::glm_dsa_sparse_mla_attention,
      "q_latent"_a,
      "q_pe"_a,
      "kv_latent"_a,
      "k_pe"_a,
      "topk_indices"_a,
      "scale"_a,
      "causal"_a = true,
      "topk_valid_prefix"_a = false,
      "causal_prefix_indices"_a = false,
      "topk_length"_a = nb::none(),
      "causal_prefix_rows"_a = 0,
      "stream"_a = nb::none());
  m.def(
      "glm_dsa_exact_block_attention",
      &omlx::glm_kernels::glm_dsa_exact_block_attention,
      "q"_a,
      "k"_a,
      "v"_a,
      "block_mask"_a,
      "block_token_mask"_a,
      "scale"_a,
      "causal"_a = true,
      "stream"_a = nb::none());
  m.def(
      "dspark_rowwise_gemm",
      &omlx::glm_kernels::dspark_rowwise_gemm,
      "lhs"_a,
      "rhs"_a,
      "transpose_rhs"_a,
      "stream"_a = nb::none());
  m.def(
      "dspark_ring_gemm",
      &omlx::glm_kernels::dspark_ring_gemm,
      "lhs"_a,
      "source"_a,
      "indices"_a,
      "transpose_rhs"_a,
      "stream"_a = nb::none());
  m.def(
      "dspark_exact_mxfp8_qmv_pair",
      &omlx::glm_kernels::dspark_exact_mxfp8_qmv_pair,
      "input"_a,
      "weight_a"_a,
      "scales_a"_a,
      "weight_b"_a,
      "scales_b"_a,
      "stream"_a = nb::none());
  m.def(
      "deepseek_v4_sparse_attention",
      &omlx::glm_kernels::deepseek_v4_sparse_attention,
      "q"_a,
      "local_kv"_a,
      "pooled"_a,
      "topk_indices"_a,
      "sinks"_a,
      "scale"_a,
      "q_offset"_a,
      "compress_ratio"_a,
      "local_window"_a,
      "stream"_a = nb::none());
  m.def(
      "glm_dsa_q8_vup_flat",
      &omlx::glm_kernels::glm_dsa_q8_vup_flat,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "biases"_a,
      "stream"_a = nb::none());
  m.def(
      "glm_moe_weighted_sum",
      &omlx::glm_kernels::glm_moe_weighted_sum,
      "x_sorted"_a,
      "inv_order"_a,
      "scores"_a,
      "stream"_a = nb::none());
  m.def(
      "deepseek_mxfp4_gather_qmm_blocks",
      &omlx::glm_kernels::deepseek_mxfp4_gather_qmm_blocks,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "block_meta"_a,
      "block_count"_a,
      "variant"_a = 0,
      "stream"_a = nb::none());
  m.def(
      "deepseek_mxfp4_gather_qmm_pair_blocks",
      &omlx::glm_kernels::deepseek_mxfp4_gather_qmm_pair_blocks,
      "x"_a,
      "weight0"_a,
      "scales0"_a,
      "weight1"_a,
      "scales1"_a,
      "block_meta"_a,
      "block_count"_a,
      "variant"_a = 0,
      "stream"_a = nb::none());
  m.def(
      "deepseek_mxfp4_gather_qmm_pair_concat_blocks",
      &omlx::glm_kernels::deepseek_mxfp4_gather_qmm_pair_concat_blocks,
      "x"_a,
      "weight0"_a,
      "scales0"_a,
      "weight1"_a,
      "scales1"_a,
      "block_meta"_a,
      "block_count"_a,
      "variant"_a = 0,
      "stream"_a = nb::none());
  m.def(
      "deepseek_affine_gather_qmm_blocks",
      &omlx::glm_kernels::deepseek_affine_gather_qmm_blocks,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "biases"_a,
      "block_meta"_a,
      "block_count"_a,
      "group_size"_a,
      "bits"_a,
      "variant"_a = 0,
      "stream"_a = nb::none());
  m.def(
      "deepseek_affine_gather_qmm_pair_concat_blocks",
      &omlx::glm_kernels::deepseek_affine_gather_qmm_pair_concat_blocks,
      "x"_a,
      "weight0"_a,
      "scales0"_a,
      "biases0"_a,
      "weight1"_a,
      "scales1"_a,
      "biases1"_a,
      "block_meta"_a,
      "block_count"_a,
      "group_size"_a,
      "bits"_a,
      "variant"_a = 0,
      "stream"_a = nb::none());
  m.def(
      "deepseek_mxfp4_gather_qmm_expert",
      &oml        elif marker == _CLOSE_MARKER:
                # Stray close outside a thought block: drop silently to keep
                # the marker out of visible content.
                if self._in_thought:
                    stream_parts.append(_THINK_CLOSE)
                    visible_parts.append(_THINK_CLOSE)
                    self._in_thought = False
            # _TURN_END_MARKER, _TOOL_RESPONSE_OPEN / _CLOSE: silent drop.

            pos = idx + advance

        return OutputParserTokenResult(
            stream_text="".join(stream_parts),
            visible_text="".join(visible_parts),
        )

    def process_token(self, token_id: int) -> OutputParserTokenResult:
        if self._detokenizer is not None:
            self._detokenizer.add_token(token_id)
            text = self._detokenizer.last_segment
        else:
            text = self._tokenizer.decode([token_id])
        return self._consume_text(text)

    def process_text(self, text: str) -> OutputParserTokenResult:
        """Process an already-detokenized text segment.

        Engines that emit text segments instead of token ids (the serial
        diffusion lane detokenizes inside ``stream_diffusion_generate``)
        feed their output through this entry point so protocol markers
        are handled identically to the token-id path.  Switches the
        session to text mode so ``finalize`` does not flush the unused
        token detokenizer.
        """
        self._text_mode = True
        if not text:
            return OutputParserTokenResult(stream_text="", visible_text="")
        return self._consume_text(text)

    def finalize(self) -> OutputParserFinalizeResult:
        text = ""
        if self._detokenizer is not None and not self._text_mode:
            self._detokenizer.finalize()
            text = self._detokenizer.last_segment

        token_result = self._consume_text(text, final=True)

        stream_text = token_result.stream_text
        visible_text = token_result.visible_text

        if self._buffer:
            stream_text += self._buffer
            visible_text += self._buffer
            self._buffer = ""

        if self._in_thought:
            stream_text += _THINK_CLOSE
            visible_text += _THINK_CLOSE
            self._in_thought = False

        return OutputParserFinalizeResult(
            stream_text=stream_text,
            visible_text=visible_text,
        )


# ===== FILE: omlx/adapter/harmony.py =====

# SPDX-License-Identifier: Apache-2.0
"""
Harmony format streaming parser for gpt-oss models.

Uses the official openai-harmony package for robust parsing.

Harmony protocol uses special tokens to structure messages:
- <|start|>: Begin message header
- <|channel|>: Mark channel type
- <|message|>: Transition to content
- <|end|>: End message
- <|return|>: Model completion signal
- <|call|>: Tool invocation signal

Message structure: <|start|>{header}<|channel|>{channel_name}<|message|>{content}<|end|>

Channels:
- final: User-visible response (plain text)
- analysis: Chain-of-thought reasoning (wrapped in <think>...</think> for streaming)
- commentary: Tool/function calls (non-streaming only)

gpt-oss also emits tool calls on the analysis channel with an explicit
``to=functions.*`` recipient; those are honored as tool calls when the
arguments form a JSON object (#2216).
"""

import json
import logging
import re
import time
from dataclasses import dataclass, field
from functools import lru_cache
from typing import Any

from openai_harmony import (
    HarmonyEncoding,
    Role,
    StreamableParser,
    load_harmony_encoding,
)

logger = logging.getLogger(__name__)

# Pattern to match <think>...</think> blocks
_THINK_TAG_PATTERN = re.compile(r"<think>.*?</think>\s*", re.DOTALL)

# Pre-allocated constants
_THINK_OPEN = "<think>\n"
_THINK_CLOSE = "</think>\n"

# Harmony special tokens that should not be streamed
_HARMONY_SPECIAL_TOKENS = [
    "<|start|>",
    "<|end|>",
    "<|message|>",
    "<|channel|>",
    "<|return|>",
    "<|call|>",
    "<|constrain|>",
]


def _has_no_real_recipient(recipi       // Wire Sparkle (or its stub) on the next runloop so any user prefs
        // saved on disk are applied before the first background check.
        DispatchQueue.main.async { [weak self] in
            self?.updates.bootstrap()
        }
    }

    func bind(server: ServerProcess?) {
        // Detach from the previous server (if any) before re-attaching.
        if self.server != nil {
            NotificationCenter.default.removeObserver(
                self,
                name: ServerProcess.stateDidChangeNotification,
                object: nil
            )
        }
        self.server = server
        if let server {
            self.serverState = server.state
            NotificationCenter.default.addObserver(
                self,
                selector: #selector(serverStateDidChange(_:)),
                name: ServerProcess.stateDidChangeNotification,
                object: server
            )
        }
    }

    @objc private func serverStateDidChange(_ note: Notification) {
        guard let proc = note.object as? ServerProcess, proc === server else { return }
        // ServerProcess posts on the main queue (via DispatchQueue.main.async
        // in terminationHandler / @MainActor health-check Task), so we're
        // already on the main thread here.
        serverState = proc.state
    }

    func updateConfig(_ next: AppConfig) {
        self.config = next
        client.configure(host: next.host, port: next.port, apiKey: next.apiKey)
    }

    func setAutoStartOnLaunch(_ enabled: Bool, persist: Bool = true) throws {
        var updated = config
        updated.autoStartOnLaunch = enabled
        if persist {
            try updated.save()
        }
        self.config = updated
    }

    // MARK: - Server lifecycle (proxied to ServerProcess)

    var hasServer: Bool { server != nil }

    @discardableResult
    func startServer() throws -> ServerProcess.StartResult? {
        try server?.start()
    }

    func stopServer() async {
        await server?.stop()
    }

    func restartServer() async throws {
        await server?.stop()
        _ = try server?.start()
    }

    func forceRestartServer() async throws {
        _ = try await server?.forceRestart()
    }

    enum BasePathChangeError: LocalizedError {
        case sameAsCurrent
        case destinationNotEmpty(String)
        case destinationNotWritable(String)
        case moveFailed(String)

        var errorDescription: String? {
            switch self {
            case .sameAsCurrent:
                return "Base path is unchanged."
            case .destinationNotEmpty(let p):
                return "\(p) already exists and isn't empty. Pick an unused folder."
            case .destinationNotWritable(let p):
                return "Can't write to \(p)."
            case .moveFailed(let m):
                return "Move failed: \(m)"
            }
        }
    }

    /// Apply pending edits to the storage layout. Both arguments are
    /// optional so the caller (Server screen → Apply) can submit only
    /// what actually changed:
    ///   • `basePath`: relocates every file under the current root, sets
    ///     `OMLX_BASE_PATH` (env + bootstrap file), and
    ///     reconfigures the spawn args.
    ///   • `modelDir` / `modelDirs`: writes the explicit model root list into
    ///     `<basePath>/settings.json`; the first entry is the primary
    ///     download target and backward-compatible `model_dir` value.
    ///   • `port`: a port change bundled into the same Apply. The spawn
    ///     uses cached `--port` args, so the restart below must carry the
    ///     new port or the server silently comes back on the old one. The
    ///     caller already PATCHed it to settings.json before us.
    /// The server is stopped once before any mutation and restarted once
    /// at the end — the user-stated rule: restart only fires when at
    /// least one of the inputs actually differs from the current config.
    func applyStorageChanges(
        basePath: String? = nil,
        modelDir: String? = nil,
      ring"&&r.match(/\./)&&(h=""),window.fromModel=!0,m(()=>ge(e,"value",h)),delete window.fromModel},n(()=>{let h=c();t.includes("unintrusive")&&document.activeElement.isSameNode(e)||e._x_forceModelUpdate(h)})});function Kt(e,t,r,n){return m(()=>{if(r instanceof CustomEvent&&r.detail!==void 0)return r.detail!==null&&r.detail!==void 0?r.detail:r.target.value;if(ze(e))if(Array.isArray(n)){let i=null;return t.includes("number")?i=Ht(r.target.value):t.includes("boolean")?i=xe(r.target.value):i=r.target.value,r.target.checked?n.includes(i)?n:n.concat([i]):n.filter(o=>!Xi(o,i))}else return r.target.checked;else{if(e.tagName.toLowerCase()==="select"&&e.multiple)return t.includes("number")?Array.from(r.target.selectedOptions).map(i=>{let o=i.value||i.text;return Ht(o)}):t.includes("boolean")?Array.from(r.target.selectedOptions).map(i=>{let o=i.value||i.text;return xe(o)}):Array.from(r.target.selectedOptions).map(i=>i.value||i.text);{let i;return Ot(e)?r.target.checked?i=r.target.value:i=n:i=r.target.value,t.includes("number")?Ht(i):t.includes("boolean")?xe(i):t.includes("trim")?i.trim():i}}})}function Ht(e){let t=e?parseFloat(e):null;return Zi(t)?t:e}function Xi(e,t){return e==t}function Zi(e){return!Array.isArray(e)&&!isNaN(e)}function En(e){return e!==null&&typeof e=="object"&&typeof e.get=="function"&&typeof e.set=="function"}d("cloak",e=>queueMicrotask(()=>m(()=>e.removeAttribute(C("cloak")))));$e(()=>`[${C("init")}]`);d("init",A((e,{expression:t},{evaluate:r})=>typeof t=="string"?!!t.trim()&&r(t,{},!1):r(t,{},!1)));d("text",(e,{expression:t},{effect:r,evaluateLater:n})=>{let i=n(t);r(()=>{i(o=>{m(()=>{e.textContent=o})})})});d("html",(e,{expression:t},{effect:r,evaluateLater:n})=>{let i=n(t);r(()=>{i(o=>{m(()=>{e.innerHTML=o,e._x_ignoreSelf=!0,S(e),delete e._x_ignoreSelf})})})});ne(Pe(":",Ie(C("bind:"))));var vn=(e,{value:t,modifiers:r,expression:n,original:i},{effect:o,cleanup:s})=>{if(!t){let c={};qr(c),x(e,n)(u=>{Tt(e,u,i)},{scope:c});return}if(t==="key")return Qi(e,n);if(e._x_inlineBindings&&e._x_inlineBindings[t]&&e._x_inlineBindings[t].extract)return;let a=x(e,n);o(()=>a(c=>{c===void 0&&typeof n=="string"&&n.match(/\./)&&(c=""),m(()=>ge(e,t,c,r))})),s(()=>{e._x_undoAddedClasses&&e._x_undoAddedClasses(),e._x_undoAddedStyles&&e._x_undoAddedStyles()})};vn.inline=(e,{value:t,modifiers:r,expression:n})=>{t&&(e._x_inlineBindings||(e._x_inlineBindings={}),e._x_inlineBindings[t]={expression:n,extract:!1})};d("bind",vn);function Qi(e,t){e._x_keyExpression=t}Le(()=>`[${C("data")}]`);d("data",(e,{expression:t},{cleanup:r})=>{if(eo(e))return;t=t===""?"{}":t;let n={};fe(n,e);let i={};Gr(i,n);let o=R(e,t,{scope:i});(o===void 0||o===!0)&&(o={}),fe(o,e);let s=T(o);Te(s);let a=k(e,s);s.init&&R(e,s.init),r(()=>{s.destroy&&R(e,s.destroy),a()})});H((e,t)=>{e._x_dataStack&&(t._x_dataStack=e._x_dataStack,t.setAttribute("data-has-alpine-state",!0))});function eo(e){return I?Be?!0:e.hasAttribute("data-has-alpine-state"):!1}d("show",(e,{modifiers:t,expression:r},{effect:n})=>{let i=x(e,r);e._x_doHide||(e._x_doHide=()=>{m(()=>{e.style.setProperty("display","none",t.includes("important")?"important":void 0)})}),e._x_doShow||(e._x_doShow=()=>{m(()=>{e.style.length===1&&e.style.display==="none"?e.removeAttribute("style"):e.style.removeProperty("display")})});let o=()=>{e._x_doHide(),e._x_isShown=!1},s=()=>{e._x_doShow(),e._x_isShown=!0},a=()=>setTimeout(s),c=he(p=>p?s():o(),p=>{typeof e._x_toggleAndCascadeWithTransitions=="function"?e._x_toggleAndCascadeWithTransitions(e,p,s,o):p?a():o()}),l,u=!0;n(()=>i(p=>{!u&&p===l||(t.includes("immediate")&&(p?a():o()),c(p),l=p,u=!1)}))});d("for",(e,{expression:t},{effect:r,cleanup:n})=>{let i=ro(t),o=x(e,i.items),s=x(e,e._x_keyExpression||"index");e._x_prevKeys=[],e._x_lookup={},r(()=>to(e,i,o,s)),n(()=>{Object.values(e._x_lookup).forEach(a=>m(()=>{P(a),a.remove()})),delete e._x_prevKeys,delete e._x_lookup})});function to(e,t,r,n){let i=s=>typeof s=="object"&&!Array.isArray(s),o=e;r(s=>{no(s)&&s>=0&&(s=Array.from(Array(s).keys(),f=>f+1)),s===void 0&&(s=[]);let a=e._x_lookup,c=e._x_prevKeys,l=[],u=[];if(i(s))s=Obx::glm_kernels::deepseek_mxfp4_gather_qmm_expert,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "indices"_a,
      "variant"_a = 0,
      "stream"_a = nb::none());
}


# ===== FILE: omlx/custom_kernels/glm_moe_dsa/csrc/deepseek_v4_sparse_attention.cpp =====

#include "deepseek_v4_sparse_attention.h"

#include <dlfcn.h>
#include <filesystem>
#include <sstream>

#include "mlx/backend/common/utils.h"
#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/kernels/steel/attn/params.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"
#include "mlx/utils.h"

namespace omlx::glm_kernels {

namespace {

using namespace mlx::core;
using namespace mlx::steel;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error("Unable to get omlx_glm_kernels binary dir.");
    }
    return std::filesystem::path(info.dli_fname).parent_path().string();
  }();
  return binary_dir;
}

inline int64_t bcast_stride(const array& a, int axis) {
  return a.shape(axis) == 1 ? 0 : a.strides(axis);
}

bool last_dim_contiguous(const array& arr) {
  return arr.strides(-1) == 1;
}

class DeepseekV4SparseAttentionPrimitive : public Primitive {
 public:
  DeepseekV4SparseAttentionPrimitive(
      Stream stream,
      float scale,
      int q_offset,
      int compress_ratio,
      int local_window)
      : Primitive(stream),
        scale_(scale),
        q_offset_(q_offset),
        compress_ratio_(compress_ratio),
        local_window_(local_window) {}

  static bool unsupported(
      const array& q,
      const array& local_kv,
      const array& pooled,
      const array& topk_indices,
      const array& sinks,
      int q_offset,
      int compress_ratio,
      int local_window,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (q.dtype() != local_kv.dtype() || q.dtype() != pooled.dtype() ||
        q.dtype() != sinks.dtype()) {
      return true;
    }
    if (q.dtype() != float16 && q.dtype() != bfloat16) {
      return true;
    }
    if (q.ndim() != 4 || local_kv.ndim() != 4 || pooled.ndim() != 3 ||
        topk_indices.ndim() != 4 || sinks.ndim() != 1) {
      return true;
    }
    if (!last_dim_contiguous(q) || !last_dim_contiguous(local_kv) ||
        !last_dim_contiguous(pooled) || !last_dim_contiguous(topk_indices) ||
        !last_dim_contiguous(sinks)) {
      return true;
    }
    if (q.shape(0) != local_kv.shape(0) || q.shape(0) != pooled.shape(0) ||
        q.shape(0) != topk_indices.shape(0) || q.shape(1) != 64 ||
        q.shape(3) != 512 || local_kv.shape(1) != 1 ||
        local_kv.shape(3) != 512 || pooled.shape(2) != 512 ||
        topk_indices.shape(1) != 1 || topk_indices.shape(2) != q.shape(2) ||
        sinks.shape(0) != q.shape(1)) {
      return true;
    }
    if (q.shape(2) <= 1 || local_kv.shape(2) < q.shape(2) ||
        pooled.shape(1) <= 0 || topk_indices.shape(3) <= 0 ||
        topk_indices.dtype() != uint32) {
      return true;
    }
    if (q_offset < 0 || compress_ratio <= 0 || local_window <= 0) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error(
        "DeepseekV4SparseAttentionPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);

    const auto& q = inputs[0];
    const auto& local_kv = inputs[1];
    const auto& pooled = inputs[2];
    const auto& topk = inputs[3];
    const auto& sinks = inputs[4];
    auto& o = outputs[0];

    constexpr int bk = 256;
    constexpr int dc = 32;
    constexpr int h = 64;
    constexpr int dim = 512;
    constexpr int wm = 8;

    const int B = q.shape(0);
    const int H = q.shape(1);
    const int qL = q.shape(2);
    const int localL = local_kv.shape(2);
    const int pooledL = pooled.shaent: str | None) -> bool:
    """Return True when the parser only preserved the primed assistant header."""
    return recipient is None or recipient == "<|start|>assistant"


def _message_content_text(msg: Any) -> str:
    """Concatenate the text parts of a parsed Harmony message."""
    text = ""
    content = getattr(msg, "content", None)
    if content is not None:
        for part in content:
            part_text = getattr(part, "text", None)
            if isinstance(part_text, str):
                text += part_text
    return text


def _is_tool_call_message(msg: Any) -> bool:
    """Return True when a parsed message is a genuine tool invocation.

    Commentary is the canonical tool-call channel. gpt-oss also emits tool
    calls on the analysis channel with an explicit functions.* recipient
    (#2216); those count only when the arguments form a JSON object, so
    recipient-less tool syntax reasoned about in thinking and prose
    addressed to a tool both stay in the reasoning output (#2032).
    """
    recipient = getattr(msg, "recipient", None)
    if not (isinstance(recipient, str) and recipient.startswith("functions.")):
        return False
    channel = getattr(msg, "channel", None)
    if channel == "commentary":
        return True
    if channel != "analysis":
        return False
    try:
        return isinstance(json.loads(_message_content_text(msg)), dict)
    except ValueError:
        return False


@lru_cache(maxsize=1)
def load_harmony_gpt_oss_encoding() -> HarmonyEncoding:
    """Load the Harmony gpt-oss encoding with a small retry window."""
    last_error: Exception | None = None
    for attempt in range(3):
        try:
            return load_harmony_encoding("HarmonyGptOss")
        except Exception as exc:
            last_error = exc
            if attempt == 2:
                break
            delay = 0.5 * (2**attempt)
            logger.warning(
                "Failed to load HarmonyGptOss encoding "
                "(attempt %d/3): %s; retrying in %.1fs",
                attempt + 1,
                exc,
                delay,
            )
            time.sleep(delay)

    assert last_error is not None
    raise last_error


def preprocess_harmony_messages(
    messages: list[dict[str, Any]]
) -> list[dict[str, Any]]:
    """
    Preprocess messages for Harmony (gpt-oss) models.

    - Strips <think> tags from assistant messages
    - Keeps tool role messages unchanged (chat_template handles conversion)

    The chat_template expects standard OpenAI format:
    - role: "tool" with tool_call_id and content
    - It uses last_tool_call.name from the previous assistant message
    - Generates: <|start|>functions.{name} to=assistant<|channel|>commentary<|message|>{content|tojson}<|end|>

    Args:
        messages: List of message dicts with 'role' and 'content' keys

    Returns:
        Messages preprocessed for Harmony format
    """
    if not messages:
        return []

    result = []

    for msg in messages:
        # Validate message is a dict
        if not isinstance(msg, dict):
            logger.warning(f"Skipping non-dict message: {type(msg)}")
            continue

        role = msg.get("role")

        if role == "assistant":
            content = msg.get("content", "")
            # Ensure content is a string (could be list in some formats)
            if isinstance(content, str):
                # Strip <think> tags
                if content and "<think>" in content:
                    content = _THINK_TAG_PATTERN.sub("", content).strip()
                    msg = {**msg, "content": content}
            elif content is not None:
                # Non-string content (e.g., list) - log but don't modify
                logger.debug(f"Assistant message has non-string content: {type(content)}")

            result.append(msg)

        else:
            # Pass through all other messages (user, tool, system, etc.) unchanged
            # Chat template handles tool messages directly using last_tool_call.name
            result.append(msg)

    return result


def _g  modelDirs: [String]? = nil,
        port: Int? = nil
    ) async throws {
        let normalizedBase = basePath.map(Self.normalize)
        let trimmedDir = modelDir?.trimmingCharacters(in: .whitespacesAndNewlines)
        let requestedModelDirs: [String]? = {
            if let modelDirs {
                return Self.cleanedModelDirs(modelDirs)
            }
            if let trimmedDir, !trimmedDir.isEmpty {
                return [Self.normalize(trimmedDir)]
            }
            return nil
        }()

        let basePathChanging: Bool = {
            guard let normalizedBase else { return false }
            return normalizedBase != Self.normalize(config.basePath)
        }()
        let modelDirChanging: Bool = {
            guard let requestedModelDirs else { return false }
            return requestedModelDirs != Self.cleanedModelDirs(config.effectiveModelDirs)
        }()

        guard basePathChanging || modelDirChanging else {
            throw BasePathChangeError.sameAsCurrent
        }

        // Stop the server BEFORE any filesystem mutation so an open log
        // file or SSD cache doesn't corrupt the move.
        if let server { await server.stop() }

        if basePathChanging, let newPath = normalizedBase {
            try migrateBasePath(to: newPath)
        }

        if modelDirChanging, let requestedModelDirs {
            var updated = config
            updated.setModelDirs(requestedModelDirs)
            try updated.save()
            self.config = updated
        }

        // Fold a bundled port change into the same single restart. Mirrors
        // applyServerEndpoint's persistence rule: the running Python server
        // owns settings.json, so we only write AppConfig to disk when the
        // server is offline. The HTTP client always needs the new endpoint.
        if let port {
            var updated = config
            updated.port = port
            if server == nil { try updated.save() }
            self.config = updated
            client.configure(host: updated.host, port: port, apiKey: updated.apiKey)
        }

        if let server {
            let baseURL = URL(fileURLWithPath: config.basePath, isDirectory: true)
            try server.reconfigure(port: port, basePath: baseURL)
            _ = try server.start()
        }
    }

    /// Move every file under the current basePath to `newPath` and persist
    /// the choice. Caller must have already stopped the server.
    private func migrateBasePath(to newPath: String) throws {
        let fm = FileManager.default
        let oldPath = Self.normalize(config.basePath)
        let oldURL = URL(fileURLWithPath: oldPath, isDirectory: true)
        let newURL = URL(fileURLWithPath: newPath, isDirectory: true)

        // Ensure the destination's parent exists. If the destination itself
        // already exists we require it to be empty so we don't accidentally
        // overwrite an unrelated folder.
        try fm.createDirectory(
            at: newURL.deletingLastPathComponent(),
            withIntermediateDirectories: true
        )
        if fm.fileExists(atPath: newURL.path) {
            let entries = (try? fm.contentsOfDirectory(atPath: newURL.path)) ?? []
            if !entries.isEmpty {
                let preview = entries.prefix(4).joined(separator: ", ")
                let suffix = entries.count > 4 ? ", …" : ""
                throw BasePathChangeError.destinationNotEmpty(
                    "\(newPath) (\(entries.count) item\(entries.count == 1 ? "" : "s"): \(preview)\(suffix))"
                )
            }
            try? fm.removeItem(at: newURL)
        }

        do {
            if fm.fileExists(atPath: oldURL.path) {
                try fm.moveItem(at: oldURL, to: newURL)
            } else {
                try fm.createDirectory(at: newURL, withIntermediateDirectories: true)
            }
        } catch {
            throw BasePathChangeError.moveFailed(error.localizedDescription)
        }

        // When the user resets to the `~/.omlx` default, clear every
        // override sject.entries(s).map(([f,g])=>{let b=Sn(t,g,f,s);n(v=>{u.includes(v)&&E("Duplicate key on x-for",e),u.push(v)},{scope:{index:f,...b}}),l.push(b)});else for(let f=0;f<s.length;f++){let g=Sn(t,s[f],f,s);n(b=>{u.includes(b)&&E("Duplicate key on x-for",e),u.push(b)},{scope:{index:f,...g}}),l.push(g)}let p=[],h=[],w=[],F=[];for(let f=0;f<c.length;f++){let g=c[f];u.indexOf(g)===-1&&w.push(g)}c=c.filter(f=>!w.includes(f));let Ee="template";for(let f=0;f<u.length;f++){let g=u[f],b=c.indexOf(g);if(b===-1)c.splice(f,0,g),p.push([Ee,f]);else if(b!==f){let v=c.splice(f,1)[0],O=c.splice(b-1,1)[0];c.splice(f,0,O),c.splice(b,0,v),h.push([v,O])}else F.push(g);Ee=g}for(let f=0;f<w.length;f++){let g=w[f];g in a&&(m(()=>{P(a[g]),a[g].remove()}),delete a[g])}for(let f=0;f<h.length;f++){let[g,b]=h[f],v=a[g],O=a[b],ee=document.createElement("div");m(()=>{O||E('x-for ":key" is undefined or invalid',o,b,a),O.after(ee),v.after(O),O._x_currentIfEl&&O.after(O._x_currentIfEl),ee.before(v),v._x_currentIfEl&&v.after(v._x_currentIfEl),ee.remove()}),O._x_refreshXForScope(l[u.indexOf(b)])}for(let f=0;f<p.length;f++){let[g,b]=p[f],v=g==="template"?o:a[g];v._x_currentIfEl&&(v=v._x_currentIfEl);let O=l[b],ee=u[b],ce=document.importNode(o.content,!0).firstElementChild,qt=T(O);k(ce,qt,o),ce._x_refreshXForScope=On=>{Object.entries(On).forEach(([Cn,Tn])=>{qt[Cn]=Tn})},m(()=>{v.after(ce),A(()=>S(ce))()}),typeof ee=="object"&&E("x-for key cannot be an object, it must be a string or an integer",o),a[ee]=ce}for(let f=0;f<F.length;f++)a[F[f]]._x_refreshXForScope(l[u.indexOf(F[f])]);o._x_prevKeys=u})}function ro(e){let t=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=/^\s*\(|\)\s*$/g,n=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,i=e.match(n);if(!i)return;let o={};o.items=i[2].trim();let s=i[1].replace(r,"").trim(),a=s.match(t);return a?(o.item=s.replace(t,"").trim(),o.index=a[1].trim(),a[2]&&(o.collection=a[2].trim())):o.item=s,o}function Sn(e,t,r,n){let i={};return/^\[.*\]$/.test(e.item)&&Array.isArray(t)?e.item.replace("[","").replace("]","").split(",").map(s=>s.trim()).forEach((s,a)=>{i[s]=t[a]}):/^\{.*\}$/.test(e.item)&&!Array.isArray(t)&&typeof t=="object"?e.item.replace("{","").replace("}","").split(",").map(s=>s.trim()).forEach(s=>{i[s]=t[s]}):i[e.item]=t,e.index&&(i[e.index]=r),e.collection&&(i[e.collection]=n),i}function no(e){return!Array.isArray(e)&&!isNaN(e)}function An(){}An.inline=(e,{expression:t},{cleanup:r})=>{let n=Y(e);n._x_refs||(n._x_refs={}),n._x_refs[t]=e,r(()=>delete n._x_refs[t])};d("ref",An);d("if",(e,{expression:t},{effect:r,cleanup:n})=>{e.tagName.toLowerCase()!=="template"&&E("x-if can only be used on a <template> tag",e);let i=x(e,t),o=()=>{if(e._x_currentIfEl)return e._x_currentIfEl;let a=e.content.cloneNode(!0).firstElementChild;return k(a,{},e),m(()=>{e.after(a),A(()=>S(a))()}),e._x_currentIfEl=a,e._x_undoIf=()=>{m(()=>{P(a),a.remove()}),delete e._x_currentIfEl},a},s=()=>{e._x_undoIf&&(e._x_undoIf(),delete e._x_undoIf)};r(()=>i(a=>{a?o():s()})),n(()=>e._x_undoIf&&e._x_undoIf())});d("id",(e,{expression:t},{evaluate:r})=>{r(t).forEach(i=>_n(e,i))});H((e,t)=>{e._x_ids&&(t._x_ids=e._x_ids)});ne(Pe("@",Ie(C("on:"))));d("on",A((e,{value:t,modifiers:r,expression:n},{cleanup:i})=>{let o=n?x(e,n):()=>{};e.tagName.toLowerCase()==="template"&&(e._x_forwardEvents||(e._x_forwardEvents=[]),e._x_forwardEvents.includes(t)||e._x_forwardEvents.push(t));let s=ae(e,t,r,a=>{o(()=>{},{scope:{$event:a},params:[a]})});i(()=>s())}));rt("Collapse","collapse","collapse");rt("Intersect","intersect","intersect");rt("Focus","trap","focus");rt("Mask","mask","mask");function rt(e,t,r){d(t,n=>E(`You can't use [x-${t}] without first installing the "${e}" plugin here: https://alpinejs.dev/plugins/${r}`,n))}K.setEvaluator(xt);K.setReactivityEngine({reactive:et,effect:rn,release:nn,raw:_});var Vt=K;window.Alpine=Vt;queueMicrotask(()=>{Vt.start()});})();


# ===== FILE: omlx/admin/static/js/dashboard.js =====

    // OCR model types that require temperature=0.0 (deterministic output)
    const OCR_CONFIG_MODEL_TYPES = new Set([
        'deepseekocr', 'deepseekocr_2', 'dots_ocr', 'glm_ocr',
pe(1);
    const int topkN = topk.shape(3);

    int64_t str_oD = 1;
    int64_t str_oL = o.shape(3);
    int64_t str_oH = o.shape(2) * str_oL;
    int64_t str_oB = o.shape(1) * str_oH;
    size_t data_size = o.shape(0) * str_oB;
    array::Flags flags{
        /* bool contiguous = */ 1,
        /* bool row_contiguous = */ 1,
        /* bool col_contiguous = */ 0,
    };
    o.set_data(
        allocator::malloc(o.nbytes()),
        data_size,
        {str_oB, str_oH, str_oL, str_oD},
        flags);

    std::string base_name;
    concatenate(
        base_name,
        "deepseek_v4_sparse_attention_",
        type_to_name(q),
        "_bk",
        bk,
        "_dc",
        dc,
        "_h",
        h,
        "_d",
        dim,
        "_wm",
        wm);

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto& compute_encoder = metal::get_command_encoder(s);
    auto kernel = d.get_kernel(base_name, lib);
    compute_encoder.set_compute_pipeline_state(kernel);

    DeepseekV4SparseAttentionParams params{
        /* int B = */ B,
        /* int H = */ H,
        /* int qL = */ qL,
        /* int localL = */ localL,
        /* int pooledL = */ pooledL,
        /* int topk = */ topkN,
        /* int local_window = */ local_window_,
        /* int compress_ratio = */ compress_ratio_,
        /* int q_offset = */ q_offset_,

        /* float scale = */ scale_,

        /* int64_t Q_strides[3] = */ {
            q.strides(0), q.strides(1), q.strides(2)},
        /* int64_t Local_strides[3] = */ {
            local_kv.strides(0),
            bcast_stride(local_kv, 1),
            local_kv.strides(2)},
        /* int64_t Pooled_strides[2] = */ {
            pooled.strides(0), pooled.strides(1)},
        /* int64_t Topk_strides[3] = */ {
            topk.strides(0), bcast_stride(topk, 1), topk.strides(2)},
        /* int64_t O_strides[3] = */ {
            o.strides(0), o.strides(1), o.strides(2)}};

    compute_encoder.set_input_array(q, 0);
    compute_encoder.set_input_array(local_kv, 1);
    compute_encoder.set_input_array(pooled, 2);
    compute_encoder.set_input_array(topk, 3);
    compute_encoder.set_input_array(sinks, 4);
    compute_encoder.set_output_array(o, 5);
    compute_encoder.set_bytes(params, 6);

    MTL::Size grid_dims = MTL::Size(qL, B, 1);
    MTL::Size group_dims = MTL::Size(32, wm, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(OMLXDeepseekV4SparseAttention)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs =
        static_cast<const DeepseekV4SparseAttentionPrimitive&>(other);
    return scale_ == rhs.scale_ && q_offset_ == rhs.q_offset_ &&
        compress_ratio_ == rhs.compress_ratio_ &&
        local_window_ == rhs.local_window_;
  }
  auto state() const {
    return std::make_tuple(
        nullptr, scale_, q_offset_, compress_ratio_, local_window_);
  }

 private:
  float scale_;
  int q_offset_;
  int compress_ratio_;
  int local_window_;
};

} // namespace

array deepseek_v4_sparse_attention(
    const array& q,
    const array& local_kv,
    const array& pooled,
    const array& topk_indices,
    const array& sinks,
    float scale,
    int q_offset,
    int compress_ratio,
    int local_window,
    StreamOrDevice s) {
  if (q.ndim() != 4 || local_kv.ndim() != 4 || pooled.ndim() != 3 ||
      topk_indices.ndim() != 4 || sinks.ndim() != 1) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_v4_sparse_attention] incompatible "
        << "ranks: " << q.shape() << ", " << local_kv.shape() << ", "
        << pooled.shape() << ", " << topk_indices.shape() << ", "
        << sinks.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (q.shape(0) != local_kv.shape(0) || q.shape(0) != pooled.shape(0) ||
      q.shape(0) != topk_indices.shape(0) || q.shape(1) != 64 ||
      q.shape(3) != 512 || local_kv.shape(1) != 1 ||
      local_kv.shape(3) != 512 || pooled.shape(2) != 512 ||
      topk_indices.shape(1) != 1 || topk_indices.shape(2) != q.et_special_token_ids(tokenizer: Any) -> set[int]:
    """
    Get special token IDs from model tokenizer.

    Args:
        tokenizer: The model's tokenizer

    Returns:
        Set of special token IDs
    """
    special_ids = set()
    for token in _HARMONY_SPECIAL_TOKENS:
        try:
            token_id = tokenizer.convert_tokens_to_ids(token)
            if isinstance(token_id, int) and token_id >= 0:
                special_ids.add(token_id)
            else:
                logger.debug(f"Harmony special token '{token}' not found in tokenizer")
        except Exception as e:
            logger.debug(f"Failed to get ID for Harmony token '{token}': {e}")
    return special_ids


@dataclass
class HarmonyStreamingParser:
    """
    Streaming parser for Harmony format using official openai-harmony package.

    Parses tokens incrementally and routes them to appropriate channels.
    Returns token IDs instead of decoded text to allow proper UTF-8 handling
    via streaming detokenizer in the caller.

    Output routing:
    - analysis channel -> stream only (wrapped in <think>...</think>)
    - final channel -> stream and visible (stored in output_text)
    - commentary channel -> buffered for tool calls (non-streaming)

    The parser returns:
    - control_text: Control strings like <think>, </think>
    - stream_token: Token ID to stream (None if not streaming)
    - visible_token: Token ID to store (None if not storing)
    - is_stop: Whether this is a stop signal
    """

    tokenizer: Any

    # Internal state (initialized in __post_init__)
    _encoding: HarmonyEncoding = field(init=False, repr=False)
    _parser: StreamableParser = field(init=False, repr=False)
    _stop_tokens: set[int] = field(init=False, default_factory=set)
    _special_tokens: set[int] = field(init=False, default_factory=set)

    # <think> tag state
    _in_think_tag: bool = field(init=False, default=False)
    _prev_channel: str | None = field(init=False, default=None)

    # Passthrough mode: activated when streaming parser encounters an
    # unrecoverable error.  Tokens are still accumulated by the scheduler
    # (request.append_output_token) so parse_tool_calls_from_tokens can
    # extract tool calls at finalization.
    _passthrough_mode: bool = field(init=False, default=False)

    def __post_init__(self):
        """Initialize the official Harmony parser."""
        self._encoding = load_harmony_gpt_oss_encoding()
        # role=None allows the parser to handle tool-call headers
        # (e.g. "assistant to=functions.Write") which Role.ASSISTANT rejects.
        self._parser = StreamableParser(self._encoding, None, strict=False)
        self._stop_tokens = set(self._encoding.stop_tokens_for_assistant_actions())
        self._special_tokens = _get_special_token_ids(self.tokenizer)

        # Prime the parser with "<|start|>assistant" tokens.  The chat
        # template already includes these in the prompt, so the model's
        # first output token is <|channel|>, not <|start|>.  Without
        # priming, the parser rejects <|channel|> as unexpected.
        self._prime_parser(self._parser)

        logger.info(
            f"Harmony parser initialized: {len(self._special_tokens)} special tokens, "
            f"{len(self._stop_tokens)} stop tokens"
        )

    def _prime_parser(self, parser: StreamableParser) -> None:
        """Feed '<|start|>assistant' header tokens so parser expects <|channel|> next."""
        start_tokens = self._encoding.encode(
            "<|start|>assistant", allowed_special="all"
        )
        for t in start_tokens:
            parser.process(t)

    def process_token(
        self, token_id: int
    ) -> tuple[str, int | None, int | None, bool]:
        """
        Process a single token and return routing information.

        This method routes tokens to appropriate channels without decoding.
        The caller should use streaming detokenizer to decode the returned
        token IDs for proper UTF-8 handling.

        Args:
            token_id: The token ID to process.

        Reto a default install isn't left with stale state.
        let isDefault = (newPath == AppConfig.defaultBasePath())
        AppConfig.persistBasePath(isDefault ? nil : newPath)

        var updated = config
        updated.basePath = newPath
        // If the explicit modelDir lived under the OLD basePath, rewrite
        // its prefix so it tags along — files were physically moved by the
        // moveItem() above, so the new path is where they actually live.
        // A modelDir outside the old basePath (e.g. /Volumes/SSD/models)
        // stays put untouched.
        updated.setModelDirs(config.effectiveModelDirs.map {
            Self.relocate(path: $0, oldBase: oldPath, newBase: newPath)
        })
        // Persist any unknown server keys at the new location — settings.json
        // moved with the directory, so this is mostly a refresh of our slice
        // for first installs that didn't have one yet.
        try? updated.save()
        self.config = updated

        // settings.json also carries path-bearing fields outside AppConfig's
        // normal slice (cache.ssd_cache_dir, logging.log_dir). When those were persisted as
        // absolute paths under the old basePath, the server reads them after
        // the move and recreates dirs at the stale path. Rewrite them here.
        // The model list is included too for older settings files and as a
        // second pass after AppConfig.save().
        // Errors are surfaced via NSLog so a silent failure is debuggable in
        // Console.app — but we don't fail the migration (move already worked).
        do {
            try Self.relocateOrphanPaths(in: AppConfig.settingsURL(basePath: newPath),
                                         oldBase: oldPath, newBase: newPath)
        } catch {
            NSLog("oMLX: relocateOrphanPaths failed: %@", String(describing: error))
        }
    }

    /// If `path` is inside `oldBase`, swap the prefix to `newBase`.
    /// Returns the input unchanged when it's empty or sits outside the
    /// migrated tree. Internal so unit tests can drive it directly. Pure —
    /// `nonisolated` so it's callable without bouncing onto MainActor.
    nonisolated static func relocate(path: String, oldBase: String, newBase: String) -> String {
        guard !path.isEmpty else { return path }
        let normalized = normalize(path)
        let oldRoot = oldBase
        if normalized == oldRoot {
            return newBase
        }
        let oldPrefix = oldRoot.hasSuffix("/") ? oldRoot : oldRoot + "/"
        if normalized.hasPrefix(oldPrefix) {
            let suffix = String(normalized.dropFirst(oldPrefix.count))
            return URL(fileURLWithPath: newBase, isDirectory: true)
                .appendingPathComponent(suffix).path
        }
        return path
    }

    /// Rewrite path-bearing fields in `<basePath>/settings.json` that may
    /// contain old-base absolute paths. Paths outside the migrated tree are
    /// left alone.
    nonisolated static func relocateOrphanPaths(in url: URL, oldBase: String, newBase: String) throws {
        NSLog("oMLX: relocateOrphanPaths in=%@ old=%@ new=%@",
              url.path, oldBase, newBase)
        guard FileManager.default.fileExists(atPath: url.path) else {
            NSLog("oMLX: relocateOrphanPaths skipped — file does not exist")
            return
        }
        let data = try Data(contentsOf: url)
        guard var json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
        else {
            NSLog("oMLX: relocateOrphanPaths skipped — root is not an object")
            return
        }

        if var model = json["model"] as? [String: Any] {
            if let dirs = model["model_dirs"] as? [String] {
                model["model_dirs"] = dirs.map {
                    Self.relocate(path: $0, oldBase: oldBase, newBase: newBase)
                }
            }
            if let dir = model["model_dir"] as? String, !dir.isEmpty {
                model["model_dir"] = Self.relocate(path: dir, oldBase: oldBase, newBase: newBase)
            }
         ]);
    const DSA_MODEL_TYPES = new Set([
        'deepseek_v32', 'glm_moe_dsa',
    ]);
    const DIFFUSION_CONFIG_MODEL_TYPES = new Set([
        'diffusion_gemma',
    ]);
    const DIFFUSION_UNSUPPORTED_PROFILE_FIELDS = new Set([
        'top_p',
        'top_k',
        'min_p',
        'repetition_penalty',
        'presence_penalty',
        'force_sampling',
        'enable_thinking',
        'preserve_thinking',
        'thinking_budget_enabled',
        'thinking_budget_tokens',
        'reasoning_parser',
        'guided_grammar_enabled',
        'guided_grammar',
        'max_tool_result_tokens',
        'index_cache_freq',
        'turboquant_kv_enabled',
        'turboquant_kv_bits',
        'turboquant_skip_last',
        'specprefill_enabled',
        'specprefill_draft_model',
        'specprefill_keep_pct',
        'specprefill_threshold',
        'dflash_enabled',
        'dflash_draft_model',
        'dflash_draft_quant_enabled',
        'dflash_draft_quant_weight_bits',
        'dflash_draft_quant_activation_bits',
        'dflash_draft_quant_group_size',
        'dflash_max_ctx',
        'dflash_in_memory_cache',
        'dflash_in_memory_cache_max_entries',
        'dflash_in_memory_cache_max_bytes',
        'dflash_ssd_cache',
        'dflash_ssd_cache_max_bytes',
        'dflash_draft_window_size',
        'dflash_draft_sink_size',
        'dflash_verify_mode',
        'mtp_enabled',
        'vlm_mtp_enabled',
        'vlm_mtp_draft_model',
        'vlm_mtp_draft_block_size',
    ]);
    const DIFFUSION_UNSUPPORTED_CT_KWARGS = new Set([
        'enable_thinking',
        'reasoning_effort',
        'preserve_thinking',
    ]);
    const VLM_MTP_DRAFTER_CONFIG_MODEL_TYPES = new Set([
        'gemma4_assistant',
        'gemma4_unified_assistant',
        'qwen3_5_mtp',
    ]);
    const DASHBOARD_MAIN_TABS = new Set(['status', 'settings', 'models', 'logs', 'bench']);
    const DASHBOARD_SETTINGS_TABS = new Set(['global', 'integrations', 'models']);
    const DASHBOARD_MODELS_TABS = new Set(['manager', 'downloader', 'quantizer', 'uploader']);
    const DASHBOARD_BENCH_TABS = new Set(['throughput', 'accuracy', 'context']);

    // Default sort for the settings and manager model tables. Also the target
    // state for the "reset sort" action.
    const MODELS_SORT_DEFAULT = { by: 'id', order: 'asc' };
    const MANAGER_SORT_DEFAULT = { by: 'name', order: 'asc' };

    function dashboard() {
        return {
            // Theme
            theme: localStorage.getItem('omlx-chat-theme') || 'auto',
            activeTheme: 'light', // Will be updated by applyTheme
            systemThemeListener: null,

            // Mobile menu
            mobileMenuOpen: false,

            // Main tab state (Status, Settings, or Logs)
            mainTab: 'status',

            activeTab: 'global',
            settingsDropdown: false,
            themeDropdown: false,

            // Global settings
            globalSettings: {
                base_path: '',
                server: { host: '127.0.0.1', port: 8000, log_level: 'info', sse_keepalive_mode: 'chunk', burst_decode_mode: 'balanced', preserve_mid_system_cache: true },
                model: { model_dirs: [''], model_fallback: false, hide_helper_models: false },
                memory: { prefill_memory_guard: true, memory_guard_tier: 'balanced', memory_guard_custom_ceiling_gb: 0 },
                scheduler: { max_concurrent_requests: 8, embedding_batch_size: 32, chunked_prefill: false, prefill_priority: 'context' },
                cache: { enabled: true, ssd_cache_dir: '', ssd_cache_max_size: 'auto', hot_cache_max_size: '0', initial_cache_blocks: 256, hot_cache_only: false },
                sampling: { max_context_window: 32768, max_context_window_policy: null, max_tokens: 32768, temperature: 1.0, top_p: 0.95, top_k: 0, repetition_penalty: 1.0 },
                mcp: { config_path: '' },
                huggingface: { endpoint: '', hf_cache_enabled: true, hf_cache_path: '' },
                network: { http_proxy: '', https_proxy: '', no_proxy: '', shape(2) ||
      sinks.shape(0) != q.shape(1)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_v4_sparse_attention] incompatible "
        << "shapes: " << q.shape() << ", " << local_kv.shape() << ", "
        << pooled.shape() << ", " << topk_indices.shape() << ", "
        << sinks.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (topk_indices.dtype() != uint32) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_v4_sparse_attention] topk_indices "
        << "must be uint32, got " << topk_indices.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto final_type = result_type(std::vector<array>{q, local_kv, pooled});
  if (final_type != float16 && final_type != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_v4_sparse_attention] expected fp16 or "
        << "bf16 inputs, got " << final_type << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  auto q_cast = astype(q, final_type, stream);
  auto local_cast = astype(local_kv, final_type, stream);
  auto pooled_cast = astype(pooled, final_type, stream);
  auto sinks_cast = astype(sinks, final_type, stream);

  if (DeepseekV4SparseAttentionPrimitive::unsupported(
          q_cast,
          local_cast,
          pooled_cast,
          topk_indices,
          sinks_cast,
          q_offset,
          compress_ratio,
          local_window,
          stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_v4_sparse_attention] unsupported DeepSeek V4 sparse attention shape.");
  }

  Shape out_shape{q_cast.shape(0), q_cast.shape(1), q_cast.shape(2), q_cast.shape(3)};
  std::vector<array> inputs = {
      q_cast, local_cast, pooled_cast, topk_indices, sinks_cast};
  return array(
      std::move(out_shape),
      final_type,
      std::make_shared<DeepseekV4SparseAttentionPrimitive>(
          stream, scale, q_offset, compress_ratio, local_window),
      std::move(inputs));
}

} // namespace omlx::glm_kernels


# ===== FILE: omlx/custom_kernels/glm_moe_dsa/csrc/dsa_indexer.cpp =====

#include "dsa_indexer.h"

#include <cstdlib>
#include <dlfcn.h>
#include <filesystem>
#include <sstream>

#include "mlx/backend/common/utils.h"
#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/kernels/steel/gemm/params.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"
#include "mlx/utils.h"

namespace omlx::glm_kernels {

namespace {

using namespace mlx::core;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error("Unable to get omlx_glm_kernels binary dir.");
    }
    return std::filesystem::path(info.dli_fname).parent_path().string();
  }();
  return binary_dir;
}

struct DSATopKParams {
  int rows;
  int L;
  int K;
  int topk;
  bool causal_valid_prefix;
};

bool row_contiguous(const array& arr) {
  return arr.flags().row_contiguous && arr.strides(-1) == 1 &&
      arr.offset() == 0;
}

array ensure_row_contiguous(const array& arr, Stream stream) {
  return contiguous(arr, false, stream);
}

class DSAIndexerScoresPrimitive : public Primitive {
 public:
  DSAIndexerScoresPrimitive(
      Stream stream,
      bool causal,
      bool weights_lh,
      int unused_causal_prefix_topk,
      bool skip_causal_future_store,
      int causal_q_offset)
      : Primitive(stream),
        causal_(causal),
        weights_lh_(weights_lh),
        unused_causal_prefix_topk_(unused_causal_prefix_topk),
        skip_causal_future_store_(skip_causal_future_store),
        causal_q_offset_(causal_q_offset) {}

  static bool unsupported(
      const array& q,
      const array& k,
      const array& weights,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (q.dtype() != k.dtype() || q.dtype() != weights.dtype()) {
      return true;
    }
    if (q.dtype() != float16 && q.dtype() != bfloat16) {
      return true;
    }
    if (!row_contiguous(qurns:
            Tuple of:
            - control_text: Control strings (<think>, </think>, etc.)
            - stream_token: Token ID to stream (None to skip)
            - visible_token: Token ID to store in output_text (None to skip)
            - is_stop: True if this is a stop token
        """
        # Check if this is a special token (should not be streamed)
        is_special_token = token_id in self._special_tokens
        is_stop = token_id in self._stop_tokens
        was_analysis = self._prev_channel == "analysis"

        # Passthrough: parser crashed earlier, buffer all tokens silently.
        # Tokens are still tracked by the scheduler for non-streaming tool
        # call extraction at finalization.
        if self._passthrough_mode:
            return "", None, None, is_stop

        try:
            self._parser.process(token_id)
        except Exception as e:
            logger.warning(
                f"Harmony streaming parser error, switching to passthrough: {e}"
            )
            self._passthrough_mode = True
            control_text = ""
            if self._in_think_tag:
                control_text = _THINK_CLOSE
                self._in_think_tag = False
            return control_text, None, None, is_stop

        channel = self._parser.current_channel
        control_text = ""

        # Harmony uses the same end token for analysis, final, and tool/action
        # messages. Ending analysis should let generation continue into the
        # final channel; ending other channels should stop the request.
        if was_analysis and is_stop:
            is_stop = False

        # Handle channel transitions for <think> tags
        if channel != self._prev_channel:
            # Close previous analysis channel
            if self._in_think_tag and self._prev_channel == "analysis":
                control_text += _THINK_CLOSE
                self._in_think_tag = False
            # Open new analysis channel
            if channel == "analysis" and not self._in_think_tag:
                control_text += _THINK_OPEN
                self._in_think_tag = True
            self._prev_channel = channel

        # Special tokens should never be streamed or stored
        if is_special_token:
            return control_text, None, None, is_stop

        # Route based on channel
        if channel == "final":
            # final: stream AND store (same token for both)
            return control_text, token_id, token_id, is_stop
        elif channel == "analysis":
            # analysis: stream only (wrapped in <think>)
            return control_text, token_id, None, is_stop
        elif channel is None:
            # Channel not yet determined (still in header parsing)
            # Buffer token but don't stream
            return control_text, None, None, is_stop
        elif channel != "commentary" and _has_no_real_recipient(
            self._parser.current_recipient
        ):
            # Some fine-tunes emit misspelled channels (for example "mardown").
            # If there is no recipient, preserve the text as user-visible output.
            return control_text, token_id, token_id, is_stop
        else:
            # commentary etc: buffer only (for tool calls)
            return control_text, None, None, is_stop

    def get_stop_token_ids(self) -> set[int]:
        """Get Harmony stop token IDs."""
        return self._stop_tokens

    def get_tool_calls(self) -> list[dict[str, str]]:
        """Get accumulated tool calls from parsed messages."""
        tool_calls = []
        try:
            messages = self._parser.messages
            if not messages:
                return tool_calls

            for msg in messages:
                if not _is_tool_call_message(msg):
                    continue

                name = msg.recipient[10:]  # Remove "functions." prefix
                content = _message_content_text(msg)

                tool_calls.append({"name": name, "arguments": content})
                logger.info(f"Extracted tool call: {name}, arguments={content}")

        ex       json["model"] = model
        }

        if var cache = json["cache"] as? [String: Any] {
            if let dir = cache["ssd_cache_dir"] as? String, !dir.isEmpty {
                cache["ssd_cache_dir"] = Self.relocate(path: dir, oldBase: oldBase, newBase: newBase)
            }
            json["cache"] = cache
        }

        if var logging = json["logging"] as? [String: Any] {
            if let dir = logging["log_dir"] as? String, !dir.isEmpty {
                logging["log_dir"] = Self.relocate(path: dir, oldBase: oldBase, newBase: newBase)
            }
            json["logging"] = logging
        }

        let out = try JSONSerialization.data(withJSONObject: json, options: [.prettyPrinted])
        try out.write(to: url, options: [.atomic])
        NSLog("oMLX: relocateOrphanPaths wrote %d bytes", out.count)
    }

    nonisolated private static func normalize(_ path: String) -> String {
        ((path as NSString).expandingTildeInPath as NSString).standardizingPath
    }

    nonisolated private static func cleanedModelDirs(_ dirs: [String]) -> [String] {
        var seen = Set<String>()
        return dirs.compactMap { raw in
            let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
            guard !trimmed.isEmpty else { return nil }
            let normalized = normalize(trimmed)
            return seen.insert(normalized).inserted ? normalized : nil
        }
    }

    /// Persist a new host/port to AppConfig, reconfigure the running server
    /// process, and bounce it. Without this, ServerScreenVM's port path in
    /// `applyServerSettings` (and `saveHost` for Listen Address) would only
    /// update the server's `settings.json`, but the next spawn still uses
    /// the cached --host / --port arguments captured at app launch.
    ///
    /// The Python server is the canonical writer of `settings.json` while
    /// it's running — the caller already PATCHed it before us, so we don't
    /// double-write here. When the server is offline (wizard dropouts,
    /// dev), we DO write so the next spawn reads the right values.
    func applyServerEndpoint(host: String? = nil, port: Int? = nil) async throws {
        let resolvedBindAddress = host ?? config.bindAddress
        let resolvedPort = port ?? config.port

        var updated = config
        updated.bindAddress = resolvedBindAddress
        updated.port = resolvedPort
        if server == nil {
            try updated.save()
        }
        self.config = updated

        // The HTTP client uses the connectable host (normalises 0.0.0.0 → 127.0.0.1).
        client.configure(host: updated.host, port: resolvedPort, apiKey: updated.apiKey)

        if let server {
            await server.stop()
            try server.reconfigure(bindAddress: resolvedBindAddress, port: resolvedPort)
            _ = try server.start()
        }
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

/// Scroll anchors inside the Server screen that other screens can deep
/// link to via `AppServices.requestedServerAnchor`. The raw value is the
/// `.id(_:)` attached to the corresponding `SectionHeader`.
enum ServerAnchor: String, Sendable {
    case defaultProfile = "server.defaultProfile"
}


# ===== FILE: apps/omlx-mac/Sources/AppView/AppView.swift =====

// AppView shell. NavigationSplitView backed by the `AppSection` enum, one
// sidebar row per screen, grouped into Server / Models / Benchmark / General
// sections. Sized close to the minimum comfortable settings window so the
// first open does not feel oversized, while still surviving a resize.
//
// The shell is the entry point for the menubar's `Admin Panel` item and is
// hosted in the SwiftUI `Window` scene declared in `oMLXApp.swift`.

import AppKit
import MarkdownUI
import SwiftUI

struct AppView: View {
    @State private var selection: AppSection? = .status
    @State private var presentedUpdate: AvailableUpdate?

    @Environment(\.colorScheme) private var scheme
    @Environment(AppServices.self) private var services

    var body: some View {ca_bundle: '' },
                auth: { api_key_set: false, api_key: '', skip_api_key_verification: false, sub_keys: [] },
                claude_code: { mode: 'cloud', opus_model: null, sonnet_model: null, haiku_model: null },
                integrations: {
                    copilot_model: null,
                    codex_model: null,
                    opencode_model: null,
                    openclaw_model: null,
                    hermes_model: null,
                    pi_model: null,
                    openclaw_tools_profile: 'full',
                    markitdown_enabled: true,
                    markitdown_expose_model: false,
                    markitdown_max_file_size_mb: 25,
                    markitdown_max_files_per_request: 5,
                    markitdown_pdf_processing_engine: 'markitdown',
                },
                ui: { language: 'en' },
                idle_timeout: { idle_timeout_seconds: null },
                system: { total_memory_bytes: 0, total_memory: '', auto_model_memory: '', ssd_total_bytes: 0, ssd_total: '' },
            },

            // Cache slider (0-100%)
            cachePercent: 10,
            editingCache: false,
            // Hot cache slider (0-50%)
            hotCachePercent: 0,
            // Editing state for direct GB input
            editingHotCache: false,

            // Idle timeout string value for select binding (null ↔ '')
            idleTimeoutValue: '',

            // Models
            models: [],
            loadingModels: false,
            reloading: false,
            // Sort state persists across refreshes/restarts via localStorage.
            sortBy: localStorage.getItem('omlx_models_sort_by') || MODELS_SORT_DEFAULT.by,
            sortOrder: localStorage.getItem('omlx_models_sort_order') || MODELS_SORT_DEFAULT.order,
            modelSearch: '',
            // Manager tab (Browse Models > Local) sort + search state.
            managerSortBy: localStorage.getItem('omlx_manager_sort_by') || MANAGER_SORT_DEFAULT.by,
            managerSortOrder: localStorage.getItem('omlx_manager_sort_order') || MANAGER_SORT_DEFAULT.order,
            managerSearch: '',

            // Auth UI state
            showApiKey: false,
            // Sub key management
            newSubKeyValue: '',
            newSubKeyName: '',
            showNewSubKeyForm: false,
            showNewSubKey: false,
            subKeyError: '',
            showSubKeys: {},

            // Saving state
            saving: false,
            saveSuccess: false,
            saveMessage: '',
            saveError: '',

            // Model settings modal
            showModelSettingsModal: false,
            selectedModel: null,
            modelSettings: {
                model_alias: '',
                model_type_override: '',
                max_context_window: null,
                max_tokens: null,
                temperature: null,
                top_p: null,
                top_k: null,
                repetition_penalty: null,
                min_p: null,
                presence_penalty: null,
                force_sampling: false,
                enableToolResultLimit: false,
                max_tool_result_tokens: null,
                ctKwargEntries: [],
                is_diffusion_model: false,
                trust_remote_code: false,
            },
            savingModelSettings: false,
            loadingGenDefaults: false,
            reasoningParsers: [],

            // Profile / template / preset state
            profiles: [],                // per-model profiles for selectedModel
            templates: [],               // global templates
            presets: [],                 // curated presets (bundled + remote refresh)
            profileFields: { universal: [], model_specific: [] },  // loaded from /api/profile-fields
            profileScope: 'model',       // 'preset' | 'global' | 'model'
            refreshingPresets: false,
            activeProfileName: null,     // currently-active profile for the form
            profilesDrift: false, ) || !row_contiguous(k) ||
        !row_contiguous(weights)) {
      return true;
    }
    if (q.ndim() != 4 || k.ndim() != 4 ||
        (weights.ndim() != 3 && weights.ndim() != 4)) {
      return true;
    }
    const bool weights_lh = weights.ndim() == 3;
    if ((q.shape(1) != 32 && q.shape(1) != 64) || k.shape(1) != 1) {
      return true;
    }
    if (weights_lh) {
      if (weights.shape(1) != q.shape(2) || weights.shape(2) != q.shape(1)) {
        return true;
      }
    } else {
      if (weights.shape(1) != q.shape(1) || weights.shape(2) != q.shape(2) ||
          weights.shape(3) != 1) {
        return true;
      }
    }
    if (q.shape(3) != 128 || k.shape(3) != 128) {
      return true;
    }
    if (q.shape(2) % 64 != 0 || k.shape(2) % 64 != 0 ||
        q.shape(3) % 16 != 0) {
      return true;
    }
    return k.shape(2) < 64;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("DSAIndexerScoresPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& q = inputs[0];
    const auto& k = inputs[1];
    const auto& weights = inputs[2];

    out.set_data(allocator::malloc(out.nbytes()));

    constexpr int bm = 64;
    constexpr int bn = 64;
    constexpr int bk = 16;
    constexpr int wm = 2;
    constexpr int wn = 2;

    const int B = q.shape(0);
    const int H = q.shape(1);
    const int M = q.shape(2);
    const int N = k.shape(2);
    const int D = q.shape(3);
    const int tiles_m = (M + bm - 1) / bm;
    const int tiles_n = (N + bn - 1) / bn;

    mlx::steel::GEMMParams params{
        /* const int M = */ M,
        /* const int N = */ N,
        /* const int K = */ D,
        /* const int lda = */ D,
        /* const int ldb = */ D,
        /* const int ldd = */ N,
        /* const int tiles_n = */ tiles_n,
        /* const int tiles_m = */ tiles_m,
        /* const int64_t batch_stride_a = */ int64_t(H) * M * D,
        /* const int64_t batch_stride_b = */ int64_t(N) * D,
        /* const int64_t batch_stride_d = */ int64_t(M) * N,
        /* const int swizzle_log = */ 0,
        /* const int gemm_k_iterations_aligned = */ D / bk,
        /* const int batch_ndim = */ 1};

    bool do_causal = causal_;
    bool use_weights_lh = weights_lh_;
    metal::MTLFCList func_consts = {
        {&do_causal, MTL::DataType::DataTypeBool, 300},
        {&use_weights_lh, MTL::DataType::DataTypeBool, 301},
    };

    std::string base_name;
    concatenate(
        base_name,
        "steel_dsa_indexer_score_",
        type_to_name(q),
        "_bm",
        bm,
        "_bn",
        bn,
        "_bk",
        bk,
        "_wm",
        wm,
        "_wn",
        wn);

    std::string hash_name;
    concatenate(
        hash_name,
        base_name,
        "_causal_",
        (do_causal ? 't' : 'n'),
        "_wlh_",
        (use_weights_lh ? 't' : 'n'));

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto& compute_encoder = metal::get_command_encoder(s);
    auto kernel = d.get_kernel(base_name, lib, hash_name, func_consts);
    compute_encoder.set_compute_pipeline_state(kernel);

    compute_encoder.set_input_array(q, 0);
    compute_encoder.set_input_array(k, 1);
    compute_encoder.set_input_array(weights, 2);
    compute_encoder.set_output_array(out, 3);
    compute_encoder.set_bytes(params, 4);
    compute_encoder.set_bytes(H, 5);
    compute_encoder.set_bytes(unused_causal_prefix_topk_, 6);
    compute_encoder.set_bytes(skip_causal_future_store_, 7);
    compute_encoder.set_bytes(causal_q_offset_, 8);

    MTL::Size group_dims = MTL::Size(wm * wn * 32, 1, 1);
    MTL::Size grid_dims = MTL::Size(tiles_n, tiles_m, B);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(OMLXDSAIndexerScores)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& othcept Exception as e:
            logger.warning(f"Error extracting tool calls: {e}")

        return tool_calls

    def finalize(self) -> str:
        """
        Finalize parsing and close any open tags.

        Returns:
            Any remaining control text (e.g., closing </think> tag).
        """
        try:
            self._parser.process_eos()
        except Exception as e:
            # Can fail if message is incomplete (e.g., missing <|end|>)
            # This is expected in some cases, so just log and continue
            logger.debug(f"Harmony parser process_eos failed (expected for incomplete messages): {e}")

        if self._in_think_tag:
            self._in_think_tag = False
            return _THINK_CLOSE
        return ""

    def reset(self) -> None:
        """Reset parser state for a new request."""
        self._parser = StreamableParser(self._encoding, None, strict=False)
        self._prime_parser(self._parser)
        self._in_think_tag = False
        self._prev_channel = None
        self._passthrough_mode = False

    @property
    def current_channel(self) -> str | None:
        """Get current channel name."""
        return self._parser.current_channel

    @property
    def current_recipient(self) -> str | None:
        """Get current recipient (for tool calls)."""
        return self._parser.current_recipient


def parse_tool_calls_from_tokens(
    token_ids: list[int],
    prepend_start: bool = True,
) -> tuple[str, str, list[dict[str, str]]]:
    """
    Parse a complete Harmony token sequence (non-streaming).

    Args:
        token_ids: Model output token ID list
        prepend_start: Whether to prepend "<|start|>assistant" tokens.
            Set to False if token_ids already includes start tokens.

    Returns:
        (output_text, analysis_text, tool_calls)
        - output_text: Text from the final channel
        - analysis_text: Chain-of-thought text from the analysis channel
        - tool_calls: [{"name": "...", "arguments": "..."}]
    """
    if not token_ids:
        return "", "", []

    try:
        encoding = load_harmony_gpt_oss_encoding()

        start_tokens = encoding.encode("<|start|>assistant", allowed_special="all")
        has_start = list(token_ids[: len(start_tokens)]) == start_tokens

        # The normal chat template includes "<|start|>assistant" in the prompt,
        # so completions start from "<|channel|>" and need the prefix restored.
        # Budget-forced or recovered Harmony completions may already include it.
        if prepend_start and not has_start:
            full_token_ids = start_tokens + list(token_ids)
        else:
            full_token_ids = list(token_ids)

        # Decode tokens for debugging
        decoded_text = encoding.decode(full_token_ids)
        logger.info(f"parse_tool_calls input ({len(full_token_ids)} tokens): {decoded_text[:300]}...")

        messages = encoding.parse_messages_from_completion_tokens(
            full_token_ids,
            role=Role.ASSISTANT,
            strict=False,
        )

        logger.info(f"Parsed {len(messages)} messages")
        for i, msg in enumerate(messages):
            content_count = len(msg.content) if msg.content else 0
            logger.info(
                f"Message {i}: channel={msg.channel}, recipient={msg.recipient}, "
                f"content_count={content_count}"
            )

        output_text = ""
        analysis_text = ""
        tool_calls = []

        for msg in messages:
            # Safely get content
            msg_content = getattr(msg, "content", None)
            if msg_content is None:
                continue

            # Checked before the analysis branch so analysis-channel tool
            # calls do not leak their arguments into reasoning text.
            if _is_tool_call_message(msg):
                name = msg.recipient[10:]  # Remove "functions." prefix
                tool_calls.append(
                    {"name": name, "arguments": _message_content_text(msg)}
                )

            elif msg.channel == "final":

        let theme = scheme == .dark ? OMLXTheme.dark : OMLXTheme.light
        let section = selectedSection

        NavigationSplitView {
            SettingsSidebar(selection: bindingForSelection())
        } detail: {
            ContentScaffold(section: section, detailTitle: detailTitle) {
                screen(for: section)
            }
        }
        .navigationSplitViewStyle(.balanced)
        .frame(minWidth: 880, idealWidth: 880, minHeight: 600, idealHeight: 600)
        // The theme resolves this through the dynamic macOS window color so
        // the shell tracks System Settings instead of a fixed canvas color.
        .background(theme.windowBg)
        .environment(\.omlxTheme, theme)
        .onChange(of: services.requestedSection, initial: true) { _, requested in
            // A screen asked us to navigate elsewhere (e.g. "Edit on
            // Server →" from the per-model Profiles tab). Clear the
            // request after applying so the same section can be requested
            // twice in a row. `initial: true` also applies a request set
            // before the window first mounted (e.g. "Model Settings…" from
            // the menubar while AppView had never been opened).
            if let requested {
                if requested != .models { services.modelDetailID = nil }
                selection = requested
                services.requestedSection = nil
            }
        }
        .onChange(of: services.updates.confirmationUpdate, initial: true) { _, update in
            presentedUpdate = update
        }
        .sheet(item: $presentedUpdate, onDismiss: {
            services.updates.dismissUpdateConfirmation()
        }) { update in
            UpdateConfirmationSheet(
                update: update,
                updates: services.updates,
                onLater: {
                    services.updates.deferUpdate(update)
                    presentedUpdate = nil
                },
                onConfirm: {
                    services.updates.confirmUpdate(update)
                    presentedUpdate = nil
                }
            )
                .environment(\.omlxTheme, theme)
        }
    }

    /// Drilling out of ModelSettingsScreen via the sidebar (changing section)
    /// must clear the per-model detail id so we don't accidentally re-enter
    /// the detail when the user returns to Models.
    private func bindingForSelection() -> Binding<AppSection?> {
        Binding(
            get: { selection },
            set: { newValue in
                guard let newValue else { return }
                if newValue != .models { services.modelDetailID = nil }
                selection = newValue
            }
        )
    }

    private var selectedSection: AppSection {
        selection ?? .status
    }

    private var detailTitle: String? {
        if selectedSection == .models, let id = services.modelDetailID, !id.isEmpty {
            return id
        }
        return nil
    }

    @ViewBuilder
    private func screen(for section: AppSection) -> some View {
        switch section {
        case .server:       ServerScreen()
        case .appearance:   AppearanceScreen()
        case .network:      NetworkScreen()
        case .performance:  PerformanceScreen()
        case .status:       StatusScreen()
        case .logs:         LogsScreen()
        case .models:
            if let id = services.modelDetailID {
                ModelSettingsScreen(modelID: id)
            } else {
                ModelsScreen()
            }
        case .downloads:    DownloadsScreen()
        case .integrations: IntegrationsScreen()
        case .quantization: QuantizationScreen()
        case .throughputBench: ThroughputBenchScreen(vm: services.throughputBench)
        case .accuracyBench:   AccuracyBenchScreen(vm: services.accuracyBench)
        case .contextBench:    ContextBenchScreen(vm: services.contextBench)
        case .security:     SecurityScreen()
        case .about:        AboutScreen()
        }
    }
}

// MARK: - Update confirmation

@MainActor
priv       // true if form values differ from active profile
            _applySeq: 0,               // monotonic counter for apply race guard
            profileError: '',
            showNewProfileForm: false,
            newProfile: { display_name: '', api_name: '', api_name_touched: false, description: '', also_as_template: false },
            showNewTemplateForm: false,
            newTemplate: { name: '', display_name: '', description: '' },
            editingProfile: null,        // profile name being edited inline
            editingTemplate: null,       // template name being edited inline
            profileDeleteConfirm: null,
            templateDeleteConfirm: null,

            // Status tab state
            stats: {
                total_prompt_tokens: 0,
                total_cached_tokens: 0,
                cache_efficiency: 0.0,
                avg_prefill_tps: 0.0,
                avg_generation_tps: 0.0,
                total_requests: 0,
                host: '127.0.0.1',
                port: 8000,
                api_key: '',
                engines: {},
                active_models: {
                    models: [],
                    model_memory_used: 0,
                    model_memory_max: 0,
                    memory_pressure: {
                        enabled: false,
                        current_bytes: 0,
                        soft_bytes: 0,
                        hard_bytes: 0,
                        pressure_level: 'ok',
                    },
                    total_active_requests: 0,
                    total_waiting_requests: 0,
                },
                runtime_cache: {
                    base_path: '',
                    ssd_cache_dir: '',
                    response_state_dir: '',
                    models: [],
                    total_num_files: 0,
                    total_size_bytes: 0,
                    effective_block_sizes: [],
                    hot_cache_size_bytes: 0,
                    hot_cache_entries: 0,
                    hot_cache_max_bytes: 0,
                    disk_max_bytes: 0,
                },
            },
            alltimeStats: {
                total_prompt_tokens: 0,
                total_cached_tokens: 0,
                cache_efficiency: 0.0,
                avg_prefill_tps: 0.0,
                avg_generation_tps: 0.0,
                total_requests: 0,
            },
            // Server connectivity info (from /admin/api/server-info)
            serverAliases: [],
            selectedAlias: '',

            // Server-restart state machine (driven by Settings > Server > Restart).
            // status transitions: idle → restarting → waiting → idle (success)
            //                   |                   |
            //                   |                   └─→ error (timeout / non-200)
            //                   └─→ unsupported (no menubar supervisor)
            //                   └─→ error (POST failed)
            restartServer: {
                status: 'idle',
                message: '',
            },

            statsScope: 'session',
            selectedStatsModel: '',
            showClearStatsConfirm: false,
            showClearAlltimeConfirm: false,
            showClearSsdCacheConfirm: false,
            showClearHotCacheConfirm: false,
            _statsRefreshTimer: null,

            // Log viewer state
            logContent: '',
            logLines: 500,
            logRefreshInterval: 5,  // seconds, 0 = disabled
            logAutoRefresh: false,
            logAutoScroll: true,
            logLoading: false,
            logError: '',
            logFile: 'server.log',
            logAvailableFiles: ['server.log'],
            logTotalLines: 0,
            logLastUpdated: '',
            logMinLevel: 'TRACE',
            _logRefreshTimer: null,

            // Models sub-tab state
            modelsTab: 'manager',
            modelsDropdown: false,

            // HF Mirror settings modal
            showHfMirrorModal: false,
            hfMirrorEndpoint: '',
            hfMirrorer) const override {
    const auto& rhs = static_cast<const DSAIndexerScoresPrimitive&>(other);
    return causal_ == rhs.causal_ && weights_lh_ == rhs.weights_lh_ &&
        unused_causal_prefix_topk_ == rhs.unused_causal_prefix_topk_ &&
        skip_causal_future_store_ == rhs.skip_causal_future_store_ &&
        causal_q_offset_ == rhs.causal_q_offset_;
  }
  auto state() const {
    return std::make_tuple(
        causal_,
        weights_lh_,
        unused_causal_prefix_topk_,
        skip_causal_future_store_,
        causal_q_offset_);
  }

 private:
  bool causal_;
  bool weights_lh_;
  int unused_causal_prefix_topk_;
  bool skip_causal_future_store_;
  int causal_q_offset_;
};

class DSATopKIndicesPrimitive : public Primitive {
 public:
  DSATopKIndicesPrimitive(
      Stream stream,
      int topk,
      bool bucketed,
      bool causal_valid_prefix)
      : Primitive(stream),
        topk_(topk),
        bucketed_(bucketed),
        causal_valid_prefix_(causal_valid_prefix) {}

  static bool unsupported(const array& scores, int topk, Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (scores.dtype() != float16 && scores.dtype() != bfloat16) {
      return true;
    }
    if (!row_contiguous(scores)) {
      return true;
    }
    if (scores.ndim() != 4 || scores.shape(1) != 1) {
      return true;
    }
    if (topk != 512 && topk != 2048) {
      return true;
    }
    return scores.shape(-1) < topk;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("DSATopKIndicesPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& scores = inputs[0];
    out.set_data(allocator::malloc(out.nbytes()));

    constexpr int threads = 1024;

    const int B = scores.shape(0);
    const int L = scores.shape(2);
    const int K = scores.shape(3);
    const int rows = B * L;

    std::string base_name;
    concatenate(
        base_name,
        "steel_dsa_topk_indices_",
        type_to_name(scores),
        "_topk",
        topk_,
        "_t",
        threads);

    bool bucketed = bucketed_;
    metal::MTLFCList func_consts = {
        {&bucketed, MTL::DataType::DataTypeBool, 302},
    };

    std::string hash_name;
    concatenate(
        hash_name,
        base_name,
        "_bucketed_",
        (bucketed ? 't' : 'n'));

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto& compute_encoder = metal::get_command_encoder(s);
    auto kernel = d.get_kernel(base_name, lib, hash_name, func_consts);
    compute_encoder.set_compute_pipeline_state(kernel);

    DSATopKParams params{
        /* int rows = */ rows,
        /* int L = */ L,
        /* int K = */ K,
        /* int topk = */ topk_,
        /* bool causal_valid_prefix = */ causal_valid_prefix_};

    compute_encoder.set_input_array(scores, 0);
    compute_encoder.set_output_array(out, 1);
    compute_encoder.set_bytes(params, 2);

    MTL::Size group_dims = MTL::Size(threads, 1, 1);
    MTL::Size grid_dims = MTL::Size(rows, 1, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(OMLXDSATopKIndices)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs = static_cast<const DSATopKIndicesPrimitive&>(other);
    return topk_ == rhs.topk_ && bucketed_ == rhs.bucketed_ &&
        causal_valid_prefix_ == rhs.causal_valid_prefix_;
  }
  auto state() const {
    return std::make_tuple(topk_, bucketed_, causal_valid_prefix_);
  }

 private:
  int topk_;
  bool bucketed_;
  bool causal_valid_prefix_;
};

class DSparkFP32TopKIndicesPrimitive : public Primitive {
 public:
  explicit DSparkFP32TopKIndicesPrimitive(Stream stream) : Primitive(stream) {}

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs       # Extract text from final channel
                for content in msg_content:
                    text = getattr(content, "text", None)
                    if isinstance(text, str):
                        output_text += text

            elif msg.channel == "analysis":
                # Extract chain-of-thought text from analysis channel
                for content in msg_content:
                    text = getattr(content, "text", None)
                    if isinstance(text, str):
                        analysis_text += text

            elif msg.channel != "commentary" and _has_no_real_recipient(msg.recipient):
                # Preserve malformed/unknown assistant channels as visible text
                # instead of returning an empty assistant message.
                for content in msg_content:
                    text = getattr(content, "text", None)
                    if isinstance(text, str):
                        output_text += text

        return output_text, analysis_text, tool_calls

    except Exception as e:
        logger.warning(f"Error parsing tool calls from tokens: {e}")
        return "", "", []


# ===== FILE: omlx/adapter/output_parser.py =====

# SPDX-License-Identifier: Apache-2.0
"""Generic streamed output parser sessions.

This module provides a tiny scheduler-facing abstraction for protocol-specific
output parsing.  A parser session owns any protocol state needed while a single
request is generating (e.g. Harmony channel parsing or Gemma 4 reasoning marker
suppression) and exposes a uniform token-by-token interface.
"""

from __future__ import annotations

import json
import logging
from collections.abc import Callable
from dataclasses import dataclass, field
from typing import Any, Protocol

from ..utils.tokenizer import (
    create_streaming_detokenizer,
    is_gemma4_model,
    is_harmony_model,
)
from .harmony import HarmonyStreamingParser, parse_tool_calls_from_tokens

logger = logging.getLogger(__name__)


@dataclass
class OutputParserTokenResult:
    """Per-token parser result returned during streaming."""

    stream_text: str = ""
    visible_text: str = ""
    is_stop: bool = False
    record_token: bool | None = None


@dataclass
class OutputParserFinalizeResult:
    """Final parser result returned once a request finishes."""

    stream_text: str = ""
    visible_text: str = ""
    output_text_prefix: str = ""
    tool_calls: list[dict[str, str]] = field(default_factory=list)
    finish_reason: str | None = None


class OutputParserSession(Protocol):
    """Protocol implemented by per-request output parser sessions."""

    def process_token(self, token_id: int) -> OutputParserTokenResult:
        """Process one generated token."""

    def finalize(self) -> OutputParserFinalizeResult:
        """Flush any buffered output when generation ends."""


@dataclass(frozen=True)
class OutputParserFactory:
    """Factory for creating per-request parser sessions."""

    kind: str
    create_session: Callable[[Any], OutputParserSession]
    stop_token_ids: set[int] = field(default_factory=set)
    thinking_start_text: str | None = None
    thinking_start_output_text: str | None = None
    thinking_end_text: str | None = None
    thinking_end_trailing_text: str | None = None
    # Marker strings that must survive special-token stripping so the
    # parser session can see them in the text stream.  Engines that strip
    # special tokens during detokenization (e.g. the serial diffusion
    # lane) preserve the token ids of these markers and let the parser
    # session remove them instead.
    protocol_marker_texts: tuple[str, ...] = ()


class HarmonyOutputParserSession:
    """Scheduler-facing wrapper around ``HarmonyStreamingParser``."""

    def __init__(self, tokenizer: Any, model_path: str | None = None):
        self._tokenizer = tokenizer
        self._parser = HarmonyStreamingParser(tokenizer)
        self._raw_token_ids: list[int] = []

        self._detokenizer = create_streaming_detokenizer(tokenizer, model_path)
        if self._detokenizer is not None:
            ate struct UpdateConfirmationSheet: View {
    let update: AvailableUpdate
    let updates: UpdateController
    let onLater: () -> Void
    let onConfirm: () -> Void

    @Environment(\.omlxTheme) private var theme

    private var trimmedNotes: String {
        update.notes.trimmingCharacters(in: .whitespacesAndNewlines)
    }

    private var noteBlocks: [ReleaseNotesBlock] {
        ReleaseNotesHTML.blocks(from: trimmedNotes)
    }

    private var isStaged: Bool {
        if case .ready(let ready) = updates.state {
            return ready.version == update.version
        }
        return false
    }

    var body: some View {
        VStack(spacing: 0) {
            header
            Divider()
            notesBody
            Divider()
            footer
        }
        .frame(width: 680, height: 560)
        .background(theme.windowBg)
    }

    private var header: some View {
        HStack(spacing: 12) {
            Squircle(systemSymbol: "arrow.down.circle.fill",
                     size: 34,
                     gradient: SquircleGradient.update)
            VStack(alignment: .leading, spacing: 4) {
                Text(String(localized: "update.confirm.title",
                            defaultValue: "oMLX \(update.version) is available",
                            comment: "Update confirmation sheet title; placeholder is the version"))
                    .font(.omlxText(17, weight: .semibold))
                    .foregroundStyle(theme.text)
                Text(String(localized: "update.confirm.subtitle",
                            defaultValue: "Review the release notes before downloading and relaunching.",
                            comment: "Subtitle for the update confirmation sheet"))
                    .font(.omlxText(12))
                    .foregroundStyle(theme.textSecondary)
            }
            Spacer()
            Button {
                NSWorkspace.shared.open(update.htmlURL)
            } label: {
                Image(systemName: "arrow.up.right.square")
                    .font(.system(size: 13, weight: .semibold))
            }
            .buttonStyle(.omlx(.plain, size: .small))
            .help(String(localized: "update.confirm.view_release",
                         defaultValue: "View release on GitHub",
                         comment: "Tooltip for the release link button in the update confirmation sheet"))
        }
        .padding(.horizontal, 20)
        .padding(.vertical, 16)
    }

    @ViewBuilder
    private var notesBody: some View {
        if trimmedNotes.isEmpty {
            VStack(spacing: 10) {
                Image(systemName: "doc.text.magnifyingglass")
                    .font(.system(size: 30, weight: .light))
                    .foregroundStyle(theme.textTertiary)
                Text(String(localized: "update.confirm.empty_notes",
                            defaultValue: "This release does not include detailed notes.",
                            comment: "Empty state when a GitHub release has no release notes"))
                    .font(.omlxText(13))
                    .foregroundStyle(theme.textSecondary)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .padding(24)
        } else {
            ScrollView {
                LazyVStack(alignment: .leading, spacing: 16) {
                    ForEach(noteBlocks) { block in
                        switch block {
                        case .markdown(let text):
                            Markdown(text)
                                .markdownTheme(.docC)
                                .frame(maxWidth: .infinity, alignment: .leading)
                                .textSelection(.enabled)
                        case .imageGroup(let images):
                            ReleaseNotesImageGroup(images: images)
                        }
                    }
                }
                .padding(20)
            }
        }
    }

    private var footer: some View {
        HStack(spacing: 10) {
            VStack(alignment: .leading, spacing: 3)Saving: false,

            // Update check state
            updateAvailable: false,
            latestVersion: null,
            releaseUrl: null,
            versionHover: false,
            _updateCheckTimer: null,

            // HF Downloader state
            hfRepoId: '',
            hfToken: '',
            hfDownloading: false,
            hfTasks: [],
            hfModels: [],
            hfModelsLoaded: false,
            hfError: '',
            hfSuccess: '',
            hfTokenInvalid: false,
            _hfRefreshTimer: null,
            hfDeleteConfirm: null,

            // Recommended models state
            hfRecommended: { trending: [], popular: [] },
            hfRecommendedLoaded: false,
            hfRecommendedLoading: false,
            hfRecommendedTab: 'trending',
            hfMlxOnly: true,

            // Pagination state
            hfPage: { trending: 1, popular: 1, search: 1 },
            hfPageSize: 10,

            // Search state
            hfSearchQuery: '',
            hfSearchSort: 'downloads',
            hfSearchResults: [],
            hfSearchLoading: false,
            hfSearchLoaded: false,
            hfSearchDebounceTimer: null,
            // Search filters
            hfSearchFiltersOpen: false,
            hfSearchMinParams: '',
            hfSearchMaxParams: '',
            hfSearchMaxSize: '',
            hfSearchMinSize: '',
            // Table sort state for Browse Models
            hfTableSort: 'downloads',
            hfTableSortDir: 'desc',

            // Computed: check if any filters are active
            get hfSearchFiltersActive() {
                return this.hfSearchMinParams || this.hfSearchMaxParams || this.hfSearchMaxSize || this.hfSearchMinSize;
            },

            // Search history
            hfSearchHistory: JSON.parse(localStorage.getItem('hfSearchHistory') || '[]'),
            hfSearchHistoryOpen: false,

            // Model detail modal
            hfModelDetail: null,
            hfModelDetailLoading: false,

            // ModelScope Downloader state
            downloaderSource: 'hf',
            msAvailable: false,
            msInitialized: false,
            msRepoId: '',
            msToken: '',
            msDownloading: false,
            msTasks: [],
            msError: '',
            msSuccess: '',
            _msRefreshTimer: null,

            // MS Recommended models state
            msRecommended: { trending: [], popular: [] },
            msRecommendedLoaded: false,
            msRecommendedLoading: false,
            msRecommendedTab: 'trending',
            msMlxOnly: true,

            // MS Pagination state
            msPage: { trending: 1, popular: 1, search: 1 },
            msPageSize: 10,

            // MS Search state
            msSearchQuery: '',
            msSearchSort: 'trending',
            msSearchResults: [],
            msSearchLoading: false,
            msSearchLoaded: false,
            msSearchHistory: JSON.parse(localStorage.getItem('msSearchHistory') || '[]'),
            msSearchHistoryOpen: false,
            msSearchDebounceTimer: null,

            // MS Model detail modal
            msModelDetail: null,
            msModelDetailLoading: false,

            // oQ Quantizer state
            oqModels: [],
            oqAllModels: [],
            oqModelsLoaded: false,
            oqSelectedModelPath: '',
            oqLevel: 4,
            oqStarting: false,
            oqTasks: [],
            oqError: '',
            oqSuccess: '',
            _oqRefreshTimer: null,
            // oQ Advanced Settings
            oqAdvancedOpen: false,
            oqTextOnly: false,
            oqDtype: 'bfloat16',
            oqSensitivityModelPath: '',
            oqPreserveMtp: false,
            oqMtpAssistantPath: '',
            oqEnhanced: false,
            oqeReuseImatrixCache: true,
            oqeImatrixCachePath: '',
            oqeStrictImatrix: false,

            // oQ Uploader state
            uploadHfToken: localStorage.getItem('omlx-hf-upload-token') || '',
            uploadHf*/) override {
    throw std::runtime_error("DSpark FP32 top-k has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    const auto& scores = inputs[0];
    auto& out = outputs[0];
    out.set_data(allocator::malloc(out.nbytes()));

    constexpr int topk = 512;
    constexpr int threads = 256;
    const int rows = scores.shape(0);
    DSATopKParams params{
        /* int rows = */ rows,
        /* int L = */ 1,
        /* int K = */ scores.shape(1),
        /* int topk = */ topk,
        /* bool causal_valid_prefix = */ false};

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto kernel =
        d.get_kernel("dspark_fp32_topk_indices_topk512_t256", lib);
    auto& encoder = metal::get_command_encoder(s);
    encoder.set_compute_pipeline_state(kernel);
    encoder.set_input_array(scores, 0);
    encoder.set_output_array(out, 1);
    encoder.set_bytes(params, 2);
    encoder.dispatch_threadgroups(
        MTL::Size(rows, 1, 1), MTL::Size(threads, 1, 1));
  }

  DEFINE_NAME(OMLXDSparkFP32TopKIndices)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& /* other */) const override {
    return true;
  }
  auto state() const {
    return std::make_tuple(nullptr);
  }
};

// ── DC-1: fused decode indexer scan ─────────────────────────────────────────
// One kernel computes the head-summed indexer scores for a single query position
// (s == 1) directly into [B,1,1,S] with fp32 accumulation, replacing the decode
// chain q@k^T -> relu -> *w -> head-sum that materializes four S-sized tensors
// per layer per token. K is addressed by STRIDES: capacity-backed cache slices
// are consumed in place (no ensure_row_contiguous copy). Scores come out in the
// input dtype by default (feeding the native 16-bit radix top-k) or fp32 when
// fp32_scores is set (selection then matches fp32 ground truth exactly).
struct OMLXDSADecodeParamsHost {
  int S;
  int64_t k_batch_stride;
  int64_t k_row_stride;
};

class DSADecodeScoresPrimitive : public Primitive {
 public:
  DSADecodeScoresPrimitive(Stream stream, bool fp32_scores)
      : Primitive(stream), fp32_scores_(fp32_scores) {}

  static bool unsupported(
      const array& q,
      const array& k,
      const array& w,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (q.dtype() != k.dtype() || q.dtype() != w.dtype()) {
      return true;
    }
    if (q.dtype() != float16 && q.dtype() != bfloat16) {
      return true;
    }
    if (!row_contiguous(q) || !row_contiguous(w)) {
      return true;
    }
    if (q.ndim() != 4 || k.ndim() != 4 || w.ndim() != 2) {
      return true;
    }
    // q [B,32,1,128] contiguous; k [B,1,S,128] with contiguous rows only
    // (capacity-backed slices allowed); rows must stay 16B-aligned for the
    // vec4 loads: row stride % 8 elements == 0.
    if (q.shape(1) != 32 || q.shape(2) != 1 || q.shape(3) != 128) {
      return true;
    }
    if (k.shape(0) != q.shape(0) || k.shape(1) != 1 || k.shape(3) != 128) {
      return true;
    }
    if (k.strides(3) != 1 || (k.strides(2) % 8) != 0) {
      return true;
    }
    if (w.shape(0) != q.shape(0) || w.shape(1) != 32) {
      return true;
    }
    return k.shape(2) < 1024;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("DSADecodeScoresPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& q = inputs[0];
    const auto& k = inputs[1];
    const auto& w = inputs[2];

    out.set_data(allocator::malloc(out.nbytes()));

    constexpr int threads = 256;
    const int B = q.shape(0);
    const int S = k.shape(2);
    const int blocks = (S + threads - 1) / threads;

    std::string base_name;
    concatenate(
  self._detokenizer.reset()

    def process_token(self, token_id: int) -> OutputParserTokenResult:
        control_text, stream_token, visible_token, is_stop = self._parser.process_token(
            token_id
        )
        self._raw_token_ids.append(token_id)

        stream_text = control_text
        visible_text = ""

        if stream_token is not None:
            if self._detokenizer is not None:
                self._detokenizer.add_token(stream_token)
                decoded_text = self._detokenizer.last_segment
            else:
                decoded_text = self._tokenizer.decode([stream_token])

            stream_text += decoded_text
            if visible_token is not None:
                visible_text += decoded_text
        elif visible_token is not None:
            if self._detokenizer is not None:
                self._detokenizer.add_token(visible_token)
                visible_text += self._detokenizer.last_segment
            else:
                visible_text += self._tokenizer.decode([visible_token])

        return OutputParserTokenResult(
            stream_text=stream_text,
            visible_text=visible_text,
            is_stop=is_stop,
            record_token=True,
        )

    def finalize(self) -> OutputParserFinalizeResult:
        stream_text = self._parser.finalize()
        visible_text = ""

        if self._detokenizer is not None:
            self._detokenizer.finalize()
            final_text = self._detokenizer.last_segment
            if final_text:
                stream_text += final_text
                if self._parser.current_channel == "final":
                    visible_text += final_text

        _, analysis_text, tool_calls = parse_tool_calls_from_tokens(self._raw_token_ids)
        finish_reason = "tool_calls" if tool_calls else None

        output_text_prefix = (
            f"<think>\n{analysis_text}\n</think>\n" if analysis_text else ""
        )

        return OutputParserFinalizeResult(
            stream_text=stream_text,
            visible_text=visible_text,
            output_text_prefix=output_text_prefix,
            tool_calls=tool_calls,
            finish_reason=finish_reason,
        )


def _is_cohere2_moe_model(
    model_name: str,
    model_config: dict[str, Any] | None = None,
) -> bool:
    return model_config is not None and model_config.get("model_type") == "cohere2_moe"


_MINIMAX_M3_MODEL_TYPES = {"minimax_m3", "minimax_m3_vl"}
_MINIMAX_THINK_START = "<mm:think>"
_MINIMAX_THINK_END = "</mm:think>"
_MINIMAX_EOS_TOKEN = "[e~["
_MINIMAX_SPECIAL_TOKENS = (_MINIMAX_EOS_TOKEN, "]~b]", "]~!b[", "]!p~[", "]!d~[")
_MINIMAX_TOOL_CALL_START = "]<]minimax[>[<tool_call>"
_MINIMAX_TOOL_CALL_END = "]<]minimax[>[</tool_call>"
_DEEPSEEK_V4_TOOL_CALL_START = "<｜DSML｜tool_calls>"
_DEEPSEEK_V4_TOOL_CALL_END = "</｜DSML｜tool_calls>"


def _is_deepseek_v4_model(
    model_name: str,
    tokenizer: Any,
    model_config: dict[str, Any] | None = None,
) -> bool:
    model_type = str(model_config.get("model_type", "")) if model_config else ""
    if model_type.startswith("deepseek_v4"):
        return True

    if (
        getattr(tokenizer, "tool_call_start", None) == _DEEPSEEK_V4_TOOL_CALL_START
        and getattr(tokenizer, "tool_call_end", None) == _DEEPSEEK_V4_TOOL_CALL_END
    ):
        return True

    return "deepseek-v4" in model_name.lower() or "deepseek_v4" in model_name.lower()


def _serialize_minimax_tool_arguments(arguments: Any) -> str:
    if isinstance(arguments, str):
        return arguments or "{}"
    if arguments is None:
        return "{}"
    try:
        return json.dumps(arguments, ensure_ascii=False, separators=(",", ":"))
    except TypeError:
        return str(arguments)


def _is_minimax_m3_model(
    model_name: str,
    model_config: dict[str, Any] | None = None,
) -> bool:
    model_type = model_config.get("model_type") if model_config else None
    if model_type in _MINIMAX_M3_MODEL_TYPES:
        return True
    lowered = model_name.lower()
    return "minimax" in lowered and "m3" in lowered


class _MiniMaxM3ProtocolNor {
                Text(String(localized: "update.confirm.size",
                            defaultValue: "Download size: \(update.sizeText ?? "Unknown")",
                            comment: "Update confirmation download size line; placeholder is a formatted byte size or Unknown"))
                    .font(.omlxText(11))
                    .foregroundStyle(theme.textSecondary)
                Text(String(localized: "update.confirm.restart_notice",
                            defaultValue: "oMLX will quit, install the update, and relaunch.",
                            comment: "Notice explaining what happens after confirming an update"))
                    .font(.omlxText(11))
                    .foregroundStyle(theme.textTertiary)
            }
            Spacer()
            Button(String(localized: "update.confirm.later",
                          defaultValue: "Later",
                          comment: "Dismiss button in the update confirmation sheet")) {
                onLater()
            }
            .buttonStyle(.omlx(.normal))
            Button(primaryButtonTitle) {
                onConfirm()
            }
            .buttonStyle(.omlx(.primary))
        }
        .padding(.horizontal, 20)
        .padding(.vertical, 14)
    }

    private var primaryButtonTitle: String {
        if isStaged {
            return String(localized: "update.confirm.install_ready",
                          defaultValue: "Install & Relaunch",
                          comment: "Primary button when the update is already staged")
        }
        return String(localized: "update.confirm.install",
                      defaultValue: "Download, Install & Relaunch",
                      comment: "Primary button to download, install, and relaunch")
    }
}

private enum ReleaseNotesBlock: Identifiable {
    case markdown(String)
    case imageGroup([ReleaseNotesImage])

    var id: String {
        switch self {
        case .markdown(let text):
            return "markdown:\(text.hashValue)"
        case .imageGroup(let images):
            return "images:\(images.map(\.id).joined(separator: ","))"
        }
    }
}

private struct ReleaseNotesImage: Identifiable, Equatable {
    let url: URL
    let alt: String

    var id: String { "\(url.absoluteString):\(alt)" }
}

private enum ReleaseNotesHTML {
    private static let imageParagraphPattern = #"(?is)<p\b[^>]*>\s*((?:<img\b[^>]*>\s*)+)</p>"#
    private static let imagePattern = #"(?is)<img\b([^>]*)>"#
    private static let attributePattern = #"([A-Za-z_:][-A-Za-z0-9_:.]*)\s*=\s*(['"])(.*?)\2"#

    static func blocks(from raw: String) -> [ReleaseNotesBlock] {
        guard let paragraphRegex = try? NSRegularExpression(pattern: imageParagraphPattern) else {
            return markdownBlocks(raw)
        }

        var blocks: [ReleaseNotesBlock] = []
        var cursor = raw.startIndex
        let fullRange = NSRange(raw.startIndex..<raw.endIndex, in: raw)
        let matches = paragraphRegex.matches(in: raw, range: fullRange)

        for match in matches {
            guard let matchRange = Range(match.range, in: raw) else { continue }
            appendMarkdown(String(raw[cursor..<matchRange.lowerBound]), to: &blocks)

            if match.numberOfRanges > 1,
               let bodyRange = Range(match.range(at: 1), in: raw) {
                let images = extractImages(from: String(raw[bodyRange]))
                if images.isEmpty {
                    appendMarkdown(String(raw[matchRange]), to: &blocks)
                } else {
                    blocks.append(.imageGroup(images))
                }
            }

            cursor = matchRange.upperBound
        }

        appendMarkdown(String(raw[cursor..<raw.endIndex]), to: &blocks)
        return blocks.isEmpty ? markdownBlocks(raw) : blocks
    }

    private static func markdownBlocks(_ raw: String) -> [ReleaseNotesBlock] {
        let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
        return trimmed.isEmpty ? [] : [.markdown(trimmed)]
    }

    private static func appendMarkdown(_ rawUsername: '',
            uploadHfOrgs: [],
            uploadHfNamespace: '',
            uploadTokenValidated: false,
            uploadTokenValidating: false,
            uploadOqModels: [],
            uploadAllModels: [],
            uploadOqModelsLoaded: false,
            uploadTasks: [],
            uploadError: '',
            uploadSuccess: '',
            _uploadRefreshTimer: null,
            // Upload modal
            uploadModalOpen: false,
            uploadModalModelPath: '',
            uploadModalModelName: '',
            uploadModalRepoId: '',
            uploadReadmeSource: '',
            uploadAutoReadme: true,
            uploadPrivate: false,
            uploadStarting: false,

            // Benchmark state
            benchModelId: '',
            benchContextProfile: 'code_python',
            benchPromptLengths: { 1024: true, 4096: true, 8192: false, 16384: false, 32768: false, 65536: false, 131072: false, 200000: false },
            benchBatchSizes: { 2: true, 4: true, 8: false },
            benchForceLmEngine: false,
            benchAdvancedOptionsOpen: false,
            benchExternalEnabled: false,
            // Shared external endpoint settings (persisted in localStorage,
            // used by both the throughput and accuracy bench tabs)
            externalBaseUrl: localStorage.getItem('omlx_bench_external_base_url') || '',
            externalApiKey: localStorage.getItem('omlx_bench_external_api_key') || '',
            externalModel: localStorage.getItem('omlx_bench_external_model') || '',
            // { base_url, model } snapshot of the current run when external
            // (no API key — used for the text export header)
            benchRunExternal: null,
            benchRunning: false,
            benchBenchId: null,
            benchProgress: null,
            benchSingleResults: [],
            benchBatchResults: [],
            benchError: '',
            benchEventSource: null,
            benchShowMetrics: false,
            benchShowText: false,
            benchCopied: false,
            benchTip: null,
            benchDeviceInfo: null,
            benchUploadResults: [],
            benchUploadDone: null,
            benchUploading: false,
            benchUploadSkipped: null,  // { reason } — only external-endpoint runs skip now
            benchUploadFlags: [],      // [{key, label}] acceleration active during the run
            // { bench_id, model_id } when the server reports a running bench
            // that is NOT the one this tab is displaying. Drives the "another
            // bench is running" banner + disables Start so the user doesn't
            // race a 409 on the server.
            benchOtherActive: null,

            // Bench sub-tab & dropdown
            benchTab: 'throughput',
            benchDropdown: false,

            // Context benchmark state
            ctxBenchModelId: '',
            ctxBenchTarget: 131072,
            ctxBenchRunning: false,
            ctxBenchBenchId: null,
            ctxBenchProgress: null,   // { phase, progress, message }
            ctxBenchResult: null,
            ctxBenchError: '',
            ctxBenchEventSource: null,

            // Accuracy benchmark state
            accModelId: '',
            accBenchmarks: { mmlu: true, mmlu_pro: false, kmmlu: false, cmmlu: false, jmmlu: false, hellaswag: false, truthfulqa: true, arc_challenge: false, winogrande: false, gsm8k: false, mathqa: false, humaneval: true, mbpp: false, livecodebench: false, bbq: false, safetybench: false },
            accSampleSizes: { mmlu: 1000, mmlu_pro: 300, kmmlu: 300, cmmlu: 300, jmmlu: 300, hellaswag: 200, truthfulqa: 0, arc_challenge: 300, winogrande: 300, gsm8k: 100, mathqa: 300, humaneval: 0, mbpp: 200, livecodebench: 100, bbq: 300, safetybench: 300 },
            accBenchmarkGroups: [
                {
                    name: 'Knowledge',
                    benchmarks: [
                        { key: 'mmlu', label: 'MMLU', desc: 'Knowledge · 57 subjects', fullSize: 14042, sizes: [30, 50, 100, 200, 300, 500, 1000, 2000]      base_name,
        "dsa_decode_scores_",
        type_to_name(q),
        fp32_scores_ ? "_of32" : "_osame",
        "_h32_d128_t",
        threads);

    OMLXDSADecodeParamsHost params{
        /* int S = */ S,
        /* int64_t k_batch_stride = */ k.shape(0) == 1 ? 0 : k.strides(0),
        /* int64_t k_row_stride = */ k.strides(2)};

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto& compute_encoder = metal::get_command_encoder(s);
    auto kernel = d.get_kernel(base_name, lib);
    compute_encoder.set_compute_pipeline_state(kernel);

    compute_encoder.set_input_array(q, 0);
    compute_encoder.set_input_array(k, 1);
    compute_encoder.set_input_array(w, 2);
    compute_encoder.set_output_array(out, 3);
    compute_encoder.set_bytes(params, 4);

    MTL::Size group_dims = MTL::Size(threads, 1, 1);
    MTL::Size grid_dims = MTL::Size(blocks, 1, B);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(OMLXDSADecodeScores)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs = static_cast<const DSADecodeScoresPrimitive&>(other);
    return fp32_scores_ == rhs.fp32_scores_;
  }
  auto state() const {
    return std::make_tuple(fp32_scores_);
  }

 private:
  bool fp32_scores_;
};

array dsa_topk_indices_impl(
    const array& scores,
    int topk,
    bool bucketed,
    bool causal_valid_prefix,
    StreamOrDevice s) {
  if (scores.ndim() != 4 || scores.shape(1) != 1) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_topk_indices] expected scores with shape "
        << "[B, 1, L, K], got " << scores.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (topk <= 0 || topk > scores.shape(-1)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_topk_indices] invalid topk " << topk
        << " for scores with shape " << scores.shape() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  auto scores_contiguous = ensure_row_contiguous(scores, stream);
  std::vector<array> inputs = {scores_contiguous};
  if (DSATopKIndicesPrimitive::unsupported(scores_contiguous, topk, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.dsa_topk_indices] unsupported M3 GLM shape.");
  }

  Shape out_shape{
      scores_contiguous.shape(0), 1, scores_contiguous.shape(2), topk};
  return array(
      std::move(out_shape),
      uint32,
      std::make_shared<DSATopKIndicesPrimitive>(
          stream, topk, bucketed, causal_valid_prefix),
      std::move(inputs));
}

} // namespace

array dsa_indexer_scores(
    const array& queries,
    const array& keys,
    const array& weights,
    bool causal,
    int unused_causal_prefix_topk,
    bool skip_causal_future_store,
    int causal_q_offset,
    StreamOrDevice s) {
  if (queries.ndim() != 4 || keys.ndim() != 4 ||
      (weights.ndim() != 3 && weights.ndim() != 4)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_indexer_scores] expected q/k rank 4 and "
        << "weights rank 3 or 4, got " << queries.shape() << ", "
        << keys.shape() << ", " << weights.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (keys.shape(1) != 1) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.dsa_indexer_scores] keys must have a singleton "
        "indexer head axis.");
  }
  const bool weights_lh = weights.ndim() == 3;
  bool weights_match = false;
  if (weights_lh) {
    weights_match = weights.shape(1) == queries.shape(2) &&
        weights.shape(2) == queries.shape(1);
  } else {
    weights_match = weights.shape(1) == queries.shape(1) &&
        weights.shape(2) == queries.shape(2) && weights.shape(3) == 1;
  }
  if (queries.shape(0) != keys.shape(0) ||
      queries.shape(0) != weights.shape(0) || !weights_match ||
      queries.shape(3) != keys.shape(3)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_indexer_scores] incompatible q, k, "
        << "weights shapes: " << queries.shape() << ", " << keys.shape()
       malizer:
    """Normalize MiniMax M3 protocol markers to oMLX-visible markers."""

    _REPLACEMENTS = (
        (_MINIMAX_THINK_START, "<think>"),
        (_MINIMAX_THINK_END, "</think>"),
        *tuple((token, "") for token in _MINIMAX_SPECIAL_TOKENS),
    )
    _MARKERS = tuple(marker for marker, _ in _REPLACEMENTS)

    def __init__(self) -> None:
        self._buffer = ""

    @classmethod
    def _replace_markers(cls, text: str) -> str:
        for marker, replacement in cls._REPLACEMENTS:
            text = text.replace(marker, replacement)
        return text

    @classmethod
    def _partial_suffix_len(cls, text: str) -> int:
        max_len = min(len(text), max(len(marker) for marker in cls._MARKERS) - 1)
        for size in range(max_len, 0, -1):
            suffix = text[-size:]
            if any(marker.startswith(suffix) for marker in cls._MARKERS):
                return size
        return 0

    def feed(self, text: str) -> str:
        if not text:
            return ""

        self._buffer += text
        keep = self._partial_suffix_len(self._buffer)
        if keep:
            ready = self._buffer[:-keep]
            self._buffer = self._buffer[-keep:]
        else:
            ready = self._buffer
            self._buffer = ""
        return self._replace_markers(ready)

    def finish(self) -> str:
        text = self._replace_markers(self._buffer)
        self._buffer = ""
        return text


def _token_id_for_text(tokenizer: Any, text: str) -> int | None:
    try:
        token_id = tokenizer.convert_tokens_to_ids(text)
    except (AttributeError, KeyError, TypeError, ValueError):
        token_id = None
    if token_id is not None and token_id != getattr(tokenizer, "unk_token_id", None):
        try:
            return int(token_id)
        except (TypeError, ValueError):
            pass

    try:
        token_ids = tokenizer.encode(text, add_special_tokens=False)
    except TypeError:
        try:
            token_ids = tokenizer.encode(text)
        except Exception:
            return None
    except Exception:
        return None

    if len(token_ids) == 1:
        try:
            return int(token_ids[0])
        except (TypeError, ValueError):
            return None
    return None


class DeepSeekV4OutputParserSession:
    """Parser session for DeepSeek V4 DSML tool-call output.

    A completed DSML tool-call block ends the assistant turn. Without a
    parser-owned stop, batched decode keeps the row alive after
    ``</｜DSML｜tool_calls>`` and the model may emit additional or malformed
    DSML fragments as visible assistant text.
    """

    def __init__(self, tokenizer: Any, model_path: str | None = None):
        self._tokenizer = tokenizer
        self._raw_text = ""
        self._stopped = False
        self._detokenizer = create_streaming_detokenizer(tokenizer, model_path)
        if self._detokenizer is not None:
            self._detokenizer.reset()

        try:
            from ..api.tool_calling import ToolCallStreamFilter

            self._stream_filter = ToolCallStreamFilter(tokenizer)
            self._visible_filter = ToolCallStreamFilter(tokenizer)
        except Exception as e:  # noqa: BLE001
            logger.debug("DeepSeek V4 stream filter unavailable: %s", e)
            self._stream_filter = None
            self._visible_filter = None

    def _decode_token(self, token_id: int) -> str:
        if self._detokenizer is not None:
            self._detokenizer.add_token(token_id)
            return self._detokenizer.last_segment
        try:
            return self._tokenizer.decode([token_id], skip_special_tokens=False)
        except TypeError:
            return self._tokenizer.decode([token_id])

    def _filtered_text(self, text: str, tool_filter: Any) -> str:
        if not text:
            return ""
        if tool_filter is not None:
            return tool_filter.feed(text)
        return text

    def _finish_filtered_text(self, tool_filter: Any) -> str:
        if tool_filter is None:
            return ""
        return tool_filter.finish()

: String, to blocks: inout [ReleaseNotesBlock]) {
        let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
        if !trimmed.isEmpty {
            blocks.append(.markdown(trimmed))
        }
    }

    private static func extractImages(from html: String) -> [ReleaseNotesImage] {
        guard let imageRegex = try? NSRegularExpression(pattern: imagePattern) else { return [] }
        let fullRange = NSRange(html.startIndex..<html.endIndex, in: html)
        return imageRegex.matches(in: html, range: fullRange).compactMap { match in
            guard match.numberOfRanges > 1,
                  let attrsRange = Range(match.range(at: 1), in: html)
            else { return nil }

            let attrs = attributes(from: String(html[attrsRange]))
            guard let src = attrs["src"],
                  let url = URL(string: decodeHTMLEntities(src))
            else { return nil }

            return ReleaseNotesImage(
                url: url,
                alt: attrs["alt"].map(decodeHTMLEntities) ?? ""
            )
        }
    }

    private static func attributes(from raw: String) -> [String: String] {
        guard let attrRegex = try? NSRegularExpression(pattern: attributePattern) else { return [:] }
        var attrs: [String: String] = [:]
        let fullRange = NSRange(raw.startIndex..<raw.endIndex, in: raw)
        for match in attrRegex.matches(in: raw, range: fullRange) {
            guard match.numberOfRanges > 3,
                  let keyRange = Range(match.range(at: 1), in: raw),
                  let valueRange = Range(match.range(at: 3), in: raw)
            else { continue }
            attrs[String(raw[keyRange]).lowercased()] = String(raw[valueRange])
        }
        return attrs
    }

    private static func decodeHTMLEntities(_ raw: String) -> String {
        guard let data = raw.data(using: .utf8),
              let decoded = try? NSAttributedString(
                data: data,
                options: [
                    .documentType: NSAttributedString.DocumentType.html,
                    .characterEncoding: String.Encoding.utf8.rawValue,
                ],
                documentAttributes: nil
              ).string
        else { return raw }
        return decoded
    }
}

private struct ReleaseNotesImageGroup: View {
    let images: [ReleaseNotesImage]

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        HStack(alignment: .top, spacing: 8) {
            ForEach(images) { image in
                AsyncImage(url: image.url) { phase in
                    switch phase {
                    case .empty:
                        ProgressView()
                            .frame(maxWidth: .infinity, minHeight: 120)
                    case .success(let rendered):
                        rendered
                            .resizable()
                            .scaledToFit()
                            .accessibilityLabel(image.alt)
                    case .failure:
                        VStack(spacing: 8) {
                            Image(systemName: "photo")
                                .font(.system(size: 24, weight: .light))
                                .foregroundStyle(theme.textTertiary)
                            if !image.alt.isEmpty {
                                Text(image.alt)
                                    .font(.omlxText(11))
                                    .foregroundStyle(theme.textSecondary)
                                    .multilineTextAlignment(.center)
                            }
                        }
                        .frame(maxWidth: .infinity, minHeight: 120)
                    @unknown default:
                        EmptyView()
                    }
                }
                .frame(maxWidth: .infinity)
                .clipShape(RoundedRectangle(cornerRadius: 6))
                .overlay(
                    RoundedRectangle(cornerRadius: 6)
                        .stroke(theme.groupBorder.opacity(0.55), lineWidth: 1)
                )
            }
        }
 },
                        { key: 'mmlu_pro', label: 'MMLU-Pro', desc: 'Hard knowledge · 14 subjects (10-way)', fullSize: 12032, sizes: [30, 50, 100, 200, 300, 500, 1000, 2000] },
                        { key: 'kmmlu', label: 'KMMLU', desc: '한국어 지식 · 45 과목', fullSize: 35030, sizes: [30, 50, 100, 200, 300, 500, 1000, 2000] },
                        { key: 'cmmlu', label: 'CMMLU', desc: '中文知识 · 67 科目', fullSize: 11582, sizes: [30, 50, 100, 200, 300, 500, 1000, 2000] },
                        { key: 'jmmlu', label: 'JMMLU', desc: '日本語知識 · 112 科目', fullSize: 7536, sizes: [30, 50, 100, 200, 300, 500, 1000, 2000] },
                    ],
                },
                {
                    name: 'Commonsense & Reasoning',
                    benchmarks: [
                        { key: 'hellaswag', label: 'HellaSwag', desc: 'Commonsense reasoning', fullSize: 10042, sizes: [30, 50, 100, 200, 300, 500, 1000, 2000] },
                        { key: 'arc_challenge', label: 'ARC-C', desc: 'Science reasoning', fullSize: 1172, sizes: [30, 50, 100, 200, 300] },
                        { key: 'winogrande', label: 'Winogrande', desc: 'Coreference resolution', fullSize: 1267, sizes: [30, 50, 100, 200, 300] },
                        { key: 'truthfulqa', label: 'TruthfulQA', desc: 'Truthfulness', fullSize: 817, sizes: [30, 50, 100, 200, 300] },
                    ],
                },
                {
                    name: 'Math',
                    benchmarks: [
                        { key: 'gsm8k', label: 'GSM8K', desc: 'Math reasoning', fullSize: 1319, sizes: [30, 50, 100, 200, 300] },
                        { key: 'mathqa', label: 'MathQA', desc: 'Quantitative reasoning · 5-way', fullSize: 2985, sizes: [30, 50, 100, 200, 300, 500, 1000] },
                    ],
                },
                {
                    name: 'Coding',
                    benchmarks: [
                        { key: 'humaneval', label: 'HumanEval', desc: 'Function completion', fullSize: 164, sizes: [30, 50, 100] },
                        { key: 'mbpp', label: 'MBPP', desc: 'Python problems', fullSize: 500, sizes: [30, 50, 100, 200, 300] },
                        { key: 'livecodebench', label: 'LiveCodeBench', desc: 'Code generation', fullSize: 1055, sizes: [30, 50, 100, 200, 300] },
                    ],
                },
                {
                    name: 'Safety & Alignment',
                    benchmarks: [
                        { key: 'bbq', label: 'BBQ', desc: 'Social bias · 11 categories', fullSize: 10864, sizes: [30, 50, 100, 200, 300, 500, 1000, 2000] },
                        { key: 'safetybench', label: 'SafetyBench', desc: 'Safety · 7 categories', fullSize: 11435, sizes: [30, 50, 100, 200, 300, 500, 1000, 2000] },
                    ],
                },
            ],
            accBatchSize: 1,
            accEnableThinking: false,
            accSamplingProfile: 'deterministic',
            accAdvancedOptionsOpen: false,
            accExternalEnabled: false,
            // Provider-specific JSON is intentionally session-only.
            accExternalExtraBody: '',
            accRunning: false,
            accCurrentModel: '',
            accCurrentBenchId: null,
            accProgress: null,
            accAllResults: [],   // accumulated across all models
            accQueue: [],        // server queue mirror
            accError: '',
            accEventSource: null,
            accShowText: false,
            accCopied: false,

            async init() {
                // Apply theme
                this.applyTheme();
                this.applyTabStateFromUrl();

                await Promise.all([
                    this.loadGlobalSettings(),
                    this.loadModels(),
                    this.loadServerInfo(),
                    this.loadProfileFields(),
                    this.loadPresets(),
                    this.checkForUpdate()
                ]);

                this.startUpdateCheckTimer();

                await this.handleMainTabChange(this.mainTab);

                 << ", " << weights.shape() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto final_type = result_type(queries, keys, weights);
  if (final_type != float16 && final_type != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_indexer_scores] expected float16 or "
        << "bfloat16 inputs, got " << final_type << ".";
    throw std::invalid_argument(msg.str());
  }
  if (unused_causal_prefix_topk < 0) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_indexer_scores] "
        << "unused_causal_prefix_topk must be non-negative, got "
        << unused_causal_prefix_topk << ".";
    throw std::invalid_argument(msg.str());
  }
  if (causal_q_offset < -1) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_indexer_scores] causal_q_offset must be "
        << "-1 or non-negative, got " << causal_q_offset << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  auto q = ensure_row_contiguous(astype(queries, final_type, stream), stream);
  auto k = ensure_row_contiguous(astype(keys, final_type, stream), stream);
  auto w = ensure_row_contiguous(astype(weights, final_type, stream), stream);

  std::vector<array> inputs = {q, k, w};
  if (DSAIndexerScoresPrimitive::unsupported(q, k, w, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.dsa_indexer_scores] unsupported M3 GLM shape.");
  }

  Shape out_shape{q.shape(0), 1, q.shape(2), k.shape(2)};
  return array(
      std::move(out_shape),
      final_type,
      std::make_shared<DSAIndexerScoresPrimitive>(
          stream,
          causal,
          weights_lh,
          unused_causal_prefix_topk,
          skip_causal_future_store,
          causal_q_offset),
      std::move(inputs));
}

array dsa_topk_indices(
    const array& scores,
    int topk,
    bool bucketed,
    bool causal_valid_prefix,
    StreamOrDevice s) {
  return dsa_topk_indices_impl(scores, topk, bucketed, causal_valid_prefix, s);
}

array dspark_fp32_topk_indices(
    const array& scores,
    int topk,
    StreamOrDevice s) {
  if (scores.ndim() != 2 || scores.dtype() != float32 || topk != 512 ||
      scores.shape(1) < topk) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dspark_fp32_topk_indices] expected FP32 "
        << "scores [rows, K>=512] and topk=512, got " << scores.shape()
        << ", topk=" << topk << ".";
    throw std::invalid_argument(msg.str());
  }
  auto stream = to_stream(s);
  if (stream.device == Device::cpu) {
    throw std::invalid_argument("DSpark FP32 top-k requires Metal.");
  }
  auto contiguous_scores = ensure_row_contiguous(scores, stream);
  Shape out_shape{contiguous_scores.shape(0), topk};
  return array(
      std::move(out_shape),
      uint32,
      std::make_shared<DSparkFP32TopKIndicesPrimitive>(stream),
      std::vector<array>{contiguous_scores});
}

array dsa_decode_scores(
    const array& queries,
    const array& keys,
    const array& weights,
    bool fp32_scores,
    StreamOrDevice s) {
  if (queries.ndim() != 4 || keys.ndim() != 4 ||
      (weights.ndim() != 2 && weights.ndim() != 3)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_decode_scores] expected q/k rank 4 and "
        << "weights rank 2 or 3, got " << queries.shape() << ", "
        << keys.shape() << ", " << weights.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (queries.shape(2) != 1) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.dsa_decode_scores] decode kernel expects a single "
        "query position (q shape [B,H,1,D]).");
  }

  auto final_type = result_type(queries, keys, weights);
  if (final_type != float16 && final_type != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.dsa_decode_scores] expected float16 or bfloat16 "
        << "inputs, got " << final_type << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  auto q = ensure_row_contiguous(astype(queries, final_type, stream), stream);
  // K is consumed via strides — capacity-backed cache slices stay    def _trim_at_first_tool_block_end(self, text: str) -> tuple[str, bool]:
        start_idx = text.find(_DEEPSEEK_V4_TOOL_CALL_START)
        if start_idx < 0:
            return text, False
        end_idx = text.find(_DEEPSEEK_V4_TOOL_CALL_END, start_idx)
        if end_idx < 0:
            return text, False
        cutoff = end_idx + len(_DEEPSEEK_V4_TOOL_CALL_END)
        return text[:cutoff], True

    def process_token(self, token_id: int) -> OutputParserTokenResult:
        if self._stopped:
            return OutputParserTokenResult(is_stop=True, record_token=False)

        decoded_text = self._decode_token(token_id)
        combined = self._raw_text + decoded_text
        trimmed, is_stop = self._trim_at_first_tool_block_end(combined)

        feed_text = trimmed[len(self._raw_text) :]
        self._raw_text = trimmed
        self._stopped = is_stop

        return OutputParserTokenResult(
            stream_text=self._filtered_text(feed_text, self._stream_filter),
            visible_text=self._filtered_text(feed_text, self._visible_filter),
            is_stop=is_stop,
            record_token=True,
        )

    def finalize(self) -> OutputParserFinalizeResult:
        stream_text = ""
        visible_text = ""
        if self._detokenizer is not None and not self._stopped:
            self._detokenizer.finalize()
            final_text = self._detokenizer.last_segment
            if final_text:
                prev_len = len(self._raw_text)
                combined = self._raw_text + final_text
                self._raw_text, self._stopped = self._trim_at_first_tool_block_end(
                    combined
                )
                final_text = self._raw_text[prev_len:]
                stream_text += self._filtered_text(final_text, self._stream_filter)
                visible_text += self._filtered_text(final_text, self._visible_filter)

        stream_text += self._finish_filtered_text(self._stream_filter)
        visible_text += self._finish_filtered_text(self._visible_filter)

        tool_calls: list[dict[str, str]] = []
        try:
            from ..api.tool_calling import parse_tool_calls

            _, parsed_calls = parse_tool_calls(self._raw_text, self._tokenizer)
            for call in parsed_calls or []:
                tool_calls.append(
                    {
                        "id": getattr(call, "id", ""),
                        "name": call.function.name,
                        "arguments": call.function.arguments,
                    }
                )
        except Exception as e:  # noqa: BLE001
            logger.debug("DeepSeek V4 tool-call parse failed: %s", e)

        return OutputParserFinalizeResult(
            stream_text=stream_text,
            visible_text=visible_text,
            tool_calls=tool_calls,
            finish_reason="tool_calls" if tool_calls else None,
        )


class MiniMaxM3OutputParserSession:
    """Parser session for MiniMax M3 XML-style tool calls."""

    def __init__(self, tokenizer: Any, model_path: str | None = None):
        self._tokenizer = tokenizer
        self._raw_text = ""
        self._detokenizer = create_streaming_detokenizer(tokenizer, model_path)
        if self._detokenizer is not None:
            self._detokenizer.reset()

        try:
            from ..api.tool_calling import ToolCallStreamFilter

            self._stream_filter = ToolCallStreamFilter(tokenizer)
            self._visible_filter = ToolCallStreamFilter(tokenizer)
        except Exception as e:  # noqa: BLE001
            logger.debug("MiniMax M3 stream filter unavailable: %s", e)
            self._stream_filter = None
            self._visible_filter = None
        self._stream_normalizer = _MiniMaxM3ProtocolNormalizer()
        self._visible_normalizer = _MiniMaxM3ProtocolNormalizer()

    def _decode_token(self, token_id: int) -> str:
        if self._detokenizer is not None:
            self._detokenizer.add_token(token_id)
            return self._detokenizer.last_segment
        try:
            return self._tokenizer.decode([token_id], sk        .frame(maxWidth: .infinity)
    }
}

// MARK: - Sidebar

private struct SettingsSidebar: View {
    @Binding var selection: AppSection?

    var body: some View {
        List(selection: $selection) {
            Section {
                SidebarRow(section: .status)
                SidebarRow(section: .appearance)
                SidebarRow(section: .server)
                SidebarRow(section: .network)
                SidebarRow(section: .performance)
                SidebarRow(section: .logs)
            } header: {
                Text(String(localized: "sidebar.group.server",
                            defaultValue: "Server",
                            comment: "Sidebar group heading for server-related screens"))
            }
            Section {
                SidebarRow(section: .models)
                SidebarRow(section: .downloads)
                SidebarRow(section: .integrations)
                SidebarRow(section: .quantization)
            } header: {
                Text(String(localized: "sidebar.group.models",
                            defaultValue: "Models",
                            comment: "Sidebar group heading for models/downloads/quant screens"))
            }
            Section {
                SidebarRow(section: .throughputBench)
                SidebarRow(section: .accuracyBench)
                SidebarRow(section: .contextBench)
            } header: {
                Text(String(localized: "sidebar.group.benchmark",
                            defaultValue: "Benchmark",
                            comment: "Sidebar group heading for accuracy + throughput bench screens"))
            }
            Section {
                SidebarRow(section: .security)
                SidebarRow(section: .about)
            } header: {
                Text(String(localized: "sidebar.group.general",
                            defaultValue: "General",
                            comment: "Sidebar group heading for the about/integrations/logs screens"))
            }
        }
        .listStyle(.sidebar)
        .navigationSplitViewColumnWidth(min: 180, ideal: 195, max: 215)
    }
}

private struct SidebarRow: View {
    let section: AppSection

    var body: some View {
        NavigationLink(value: section) {
            Label(section.title, systemImage: section.symbol)
        }
    }
}

// MARK: - Detail scaffold

/// Wraps the per-section view with the design's toolbar title + scroll body.
/// Mirrors `ContentArea` from the design (omlx-components.jsx:250-292):
/// 42 pt toolbar, 720 pt max content width, 20/28/36 pt padding.
private struct ContentScaffold<Content: View>: View {
    let section: AppSection
    let detailTitle: String?
    @ViewBuilder var content: () -> Content

    @Environment(\.omlxTheme) private var theme
    @Environment(AppServices.self) private var services

    private var titleText: String { detailTitle ?? section.title }

    var body: some View {
        Group {
            if section.fillsContentArea {
                content()
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
                    .frame(maxWidth: 720, alignment: .topLeading)
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
                    .padding(.bottom, 18)
                    .background(theme.windowBg)
            } else {
                ScrollViewReader { proxy in
                    ScrollView {
                        content()
                        // Wrap title + content together in a single max-width
                        // frame so the section title and the cards share the
                        // same left edge (Settings.app pattern: large title
                        // sits flush with content, not offset).
                            .frame(maxWidth: 720, alignment: .topLeading)
                            .frame(maxWidth: .infinity, alignment: .top)
                            .padding(.bottom, 36)
                    }
                    // Deep-link scroll: when another screen (// Watch for main tab changes to manage refresh timers
                this.$watch('mainTab', (value) => {
                    this.handleMainTabChange(value);
                });

                // When the user returns to this browser tab after looking
                // elsewhere, re-check whether a different bench just started
                // in another tab. Fires the banner without requiring an
                // in-app tab switch.
                document.addEventListener('visibilitychange', () => {
                    if (document.visibilityState !== 'visible') return;
                    if (this.mainTab === 'bench' && this.benchTab === 'throughput') {
                        this.loadBenchState();
                    }
                });

                this.$watch('hfMlxOnly', () => {
                    this.hfRecommended = { trending: [], popular: [] };
                    this.hfRecommendedLoaded = false;
                    this.hfSearchResults = [];
                    this.hfSearchLoaded = false;
                    this.loadRecommendedModels();
                    if (this.hfSearchQuery.trim()) {
                        this.searchHFModels();
                    }
                });

                this.$watch('msMlxOnly', () => {
                    this.msRecommended = { trending: [], popular: [] };
                    this.msRecommendedLoaded = false;
                    this.msSearchResults = [];
                    this.msSearchLoaded = false;
                    this.loadMsRecommendedModels();
                    if (this.msSearchQuery.trim()) {
                        this.searchMSModels();
                    }
                });

                window.addEventListener('popstate', () => {
                    this.applyTabStateFromUrl();
                });

                // Pause stats polling when tab is hidden to reduce server load
                document.addEventListener('visibilitychange', () => {
                    if (document.hidden) {
                        this.stopStatsRefresh();
                    } else if (this.mainTab === 'status') {
                        this.loadStats();
                        this.startStatsRefresh();
                    }
                });
            },

            async handleMainTabChange(value) {
                if (value === 'status') {
                    await this.loadStats();
                    this.startStatsRefresh();
                } else {
                    this.stopStatsRefresh();
                }
                if (value === 'logs') {
                    await this.loadLogs();
                    this.startLogRefresh();
                } else {
                    this.stopLogRefresh();
                }
                if (value === 'models') {
                    const loads = [this.loadHFModels(), this.loadHFTasks(), this.loadOQTasks()];
                    if (this.modelsTab === 'downloader' && !this.hfRecommendedLoaded) {
                        loads.push(this.loadRecommendedModels());
                    }
                    if (this.modelsTab === 'quantizer') {
                        loads.push(this.loadOQModels());
                    }
                    if (this.msInitialized && this.msAvailable) {
                        loads.push(this.loadMSTasks());
                    }
                    await Promise.all(loads);
                    const hasActive = this.hfTasks.some(t =>
                        t.status === 'pending' || t.status === 'downloading');
                    if (hasActive) this.startHFRefresh();
                    const hasMsActive = this.msTasks.some(t =>
                        t.status === 'pending' || t.status === 'downloading');
                    if (hasMsActive) this.startMSRefresh();
                    const hasOqActive = this.oqTasks.some(t =>
                        ['pending', 'loading', 'quantizing', 'saving'].includes(t.status));
                    if (hasOqActive) this.startOQRefresh();
                } else {
                    this.stopHFRefresh();
                  in place.
  // (astype is a no-op on the cache's native dtype; a dtype-mismatched call
  // would still copy, which the row-stride guard then re-checks.)
  auto k = astype(keys, final_type, stream);
  auto w = astype(weights, final_type, stream);
  if (w.ndim() == 3) {
    // accept [B, 1, H]
    w = reshape(w, {w.shape(0), w.shape(2)}, stream);
  }
  w = ensure_row_contiguous(w, stream);

  std::vector<array> inputs = {q, k, w};
  if (DSADecodeScoresPrimitive::unsupported(q, k, w, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.dsa_decode_scores] unsupported shape/dtype/layout.");
  }

  Shape out_shape{q.shape(0), 1, 1, k.shape(2)};
  return array(
      std::move(out_shape),
      fp32_scores ? float32 : final_type,
      std::make_shared<DSADecodeScoresPrimitive>(stream, fp32_scores),
      std::move(inputs));
}

} // namespace omlx::glm_kernels


# ===== FILE: omlx/custom_kernels/glm_moe_dsa/csrc/dspark_gemm.cpp =====

#include "dspark_gemm.h"

#include <algorithm>
#include <dlfcn.h>
#include <filesystem>
#include <sstream>

#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/kernels/steel/gemm/params.h"
#include "mlx/backend/metal/metal.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"

namespace omlx::glm_kernels {

namespace {

using namespace mlx::core;
using namespace mlx::steel;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error("Unable to locate DSpark kernel binary.");
    }
    return std::filesystem::path(info.dli_fname).parent_path().string();
  }();
  return binary_dir;
}

int next_power_of_two(int value) {
  int result = 1;
  while (result < value) {
    result <<= 1;
  }
  return result;
}

class DSparkRowwiseGemmPrimitive : public Primitive {
 public:
  DSparkRowwiseGemmPrimitive(Stream stream, bool transpose_rhs)
      : Primitive(stream), transpose_rhs_(transpose_rhs) {}

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("DSpark rowwise GEMM has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& stream = this->stream();
    auto& device = metal::device(stream.device);
    const auto& lhs = inputs[0];
    const auto& rhs = inputs[1];
    auto& output = outputs[0];

    const bool fp32 = lhs.dtype() == float32;
    const int bm = fp32 && transpose_rhs_ ? 32 : 64;
    const int bn = fp32 ? (transpose_rhs_ ? 64 : 32)
                        : (transpose_rhs_ ? 32 : 64);
    const int bk = fp32 ? (transpose_rhs_ ? 16 : 32)
                        : (transpose_rhs_ ? 32 : 16);
    const int wm = fp32 ? (transpose_rhs_ ? 1 : 2)
                        : (transpose_rhs_ ? 2 : 1);
    constexpr int wn = 2;
    const int rows = lhs.shape(0);
    const int M = lhs.shape(1);
    const int K = lhs.shape(2);
    const int N = transpose_rhs_ ? rhs.shape(1) : rhs.shape(2);
    const int ldb = transpose_rhs_ ? K : N;

    output.set_data(allocator::malloc(output.nbytes()));
    auto library = device.get_library("omlx_glm_kernels", current_binary_dir());

    // Match the split-K choice made by an independent MLX M=1 matmul. The
    // row dimension is encoded only in grid.z, so every verify row retains
    // exactly the same partition and accumulation order as ordinary decode.
    const int tile_m = (M + 15) / 16;
    const int tile_n = (N + 15) / 16;
    const int tile_k = K / 16;
    const bool use_split_k = tile_m * tile_n <= 2048 && tile_k >= 8 &&
        K >= std::max(M, N);
    if (use_split_k) {
      constexpr int split_bm = 32;
      constexpr int split_bn = 32;
      constexpr int split_bk = 16;
      constexpr int split_wm = 2;
      constexpr int split_wn = 2;
      const int split_tiles_m = (M + split_bm - 1) / split_bm;
      const int split_tiles_n = (N + split_bn - 1) / split_bn;
      const int split_ratio =
          (K / split_bk)ip_special_tokens=False)
        except TypeError:
            return self._tokenizer.decode([token_id])

    def _filtered_text(
        self,
        text: str,
        tool_filter: Any,
        normalizer: _MiniMaxM3ProtocolNormalizer,
    ) -> str:
        if not text:
            return ""
        if tool_filter is not None:
            text = tool_filter.feed(text)
        return normalizer.feed(text)

    def _finish_filtered_text(
        self,
        tool_filter: Any,
        normalizer: _MiniMaxM3ProtocolNormalizer,
    ) -> str:
        text = ""
        if tool_filter is not None:
            text += normalizer.feed(tool_filter.finish())
        text += normalizer.finish()
        return text

    def process_token(self, token_id: int) -> OutputParserTokenResult:
        decoded_text = self._decode_token(token_id)
        self._raw_text += decoded_text
        is_stop = decoded_text == _MINIMAX_EOS_TOKEN
        return OutputParserTokenResult(
            stream_text=self._filtered_text(
                decoded_text,
                self._stream_filter,
                self._stream_normalizer,
            ),
            visible_text=self._filtered_text(
                decoded_text,
                self._visible_filter,
                self._visible_normalizer,
            ),
            is_stop=is_stop,
            record_token=not is_stop,
        )

    def finalize(self) -> OutputParserFinalizeResult:
        stream_text = ""
        visible_text = ""
        if self._detokenizer is not None:
            self._detokenizer.finalize()
            final_text = self._detokenizer.last_segment
            if final_text:
                self._raw_text += final_text
                stream_text += self._filtered_text(
                    final_text,
                    self._stream_filter,
                    self._stream_normalizer,
                )
                visible_text += self._filtered_text(
                    final_text,
                    self._visible_filter,
                    self._visible_normalizer,
                )

        stream_text += self._finish_filtered_text(
            self._stream_filter,
            self._stream_normalizer,
        )
        visible_text += self._finish_filtered_text(
            self._visible_filter,
            self._visible_normalizer,
        )

        tool_calls: list[dict[str, str]] = []
        if _MINIMAX_TOOL_CALL_START in self._raw_text:
            try:
                from ..patches.mlx_vlm_minimax_m3_compat import (
                    apply_mlx_vlm_minimax_m3_compat_patch,
                )

                apply_mlx_vlm_minimax_m3_compat_patch()

                from mlx_vlm.tool_parsers.minimax_m3 import parse_tool_call

                parsed = parse_tool_call(self._raw_text)
                parsed_calls = parsed if isinstance(parsed, list) else [parsed]
                tool_calls = [
                    {
                        "name": str(call.get("name", "")),
                        "arguments": _serialize_minimax_tool_arguments(
                            call.get("arguments")
                        ),
                    }
                    for call in parsed_calls
                    if isinstance(call, dict) and call.get("name")
                ]
            except Exception as e:  # noqa: BLE001
                logger.debug("MiniMax M3 tool-call parse failed: %s", e)

        return OutputParserFinalizeResult(
            stream_text=stream_text,
            visible_text=visible_text,
            tool_calls=tool_calls,
            finish_reason="tool_calls" if tool_calls else None,
        )


_INKLING_MODEL_TYPES = {"inkling", "inkling_mm_model"}
_INKLING_MESSAGE_MODEL = "<|message_model|>"
_INKLING_CONTENT_THINKING = "<|content_thinking|>"
_INKLING_CONTENT_TEXT = "<|content_text|>"
_INKLING_CONTENT_XML = "<|content_xml|>"
_INKLING_CONTENT_TOOL_JSON = "<|content_invoke_tool_json|>"
_INKLING_END_MESSAGE = "<|end_message|>"
_INKLING_END_SAMPLING = "<|content_model_end_sampling|>"
_INKLING_MARKERS = (
    _INKLING_MESSAGE_MODEL,
   e.g. the
                    // per-model "Edit on Server →" link) requested a
                    // jump to a named anchor *inside the section we just
                    // switched to*, scroll there once the inner view has
                    // had a runloop tick to lay out. The id includes
                    // both section and anchor so re-requesting the same
                    // anchor in the same section still fires.
                    .task(id: ScrollAnchorKey(section: section,
                                              anchor: services.requestedServerAnchor)) {
                        guard let anchor = services.requestedServerAnchor,
                              section == .server else { return }
                        // One render cycle to let ServerScreen mount its
                        // SectionHeader with the `.id()` we're targeting.
                        try? await Task.sleep(nanoseconds: 60_000_000)
                        withAnimation(.easeInOut(duration: 0.25)) {
                            proxy.scrollTo(anchor.rawValue, anchor: .top)
                        }
                        services.requestedServerAnchor = nil
                    }
                    .scrollContentBackground(.hidden)
                    .background(theme.windowBg)
                }
            }
        }
        .navigationTitle(titleText)
        .background(theme.windowBg)
    }
}

/// Composite identity used by `ContentScaffold`'s deep-link scroll
/// `.task(id:)` so the scroll fires whenever either the section or the
/// anchor changes — and re-fires if the same anchor is requested twice.
private struct ScrollAnchorKey: Equatable {
    let section: AppSection
    let anchor: ServerAnchor?
}

#Preview("AppView — light") {
    AppView()
        .frame(width: 1140, height: 760)
        .preferredColorScheme(.light)
}

#Preview("AppView — dark") {
    AppView()
        .frame(width: 1140, height: 760)
        .preferredColorScheme(.dark)
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/AboutScreen.swift =====

// PR 9 — About.
//
// Build info + license + credits + project links. The Updates section does
// NOT live here — design v2 moved it onto Status (PR 7). This screen is
// intentionally static; opening links bounces to the default browser.

import SwiftUI
import AppKit

struct AboutScreen: View {
    @Environment(\.omlxTheme) private var theme

    private var version: String {
        Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0"
    }
    private var build: String {
        Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "—"
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            HeroCard(version: version, build: build)
            ProjectSection()
            LicenseSection()
            CreditsSection()
        }
    }
}

// MARK: - Hero

private struct HeroCard: View {
    let version: String
    let build: String

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        HStack(spacing: 16) {
            // Match the ServerHeroCard / StatusScreen hero — same rounded
            // omlx mark as the Dock icon and README hero, light/dark
            // variants ship with the AppLogo imageset.
            //
            // The AppLogo SVG embeds a 10pt transparent margin inside its
            // 160pt viewBox (content occupies 140pt). Frame is scaled by
            // 160/140 so the visible rounded-square reads at the same ~60pt
            // size as the previous Squircle placeholder.
            Image("AppLogo")
                .resizable()
                .interpolation(.high)
                .frame(width: 69, height: 69)
            VStack(alignment: .leading, spacing: 4) {
                Text("oMLX")
                    .font(.omlxText(22, weight: .semibold))
                    .foregroundStyle(theme.text)
                Text(String(localized: "about.hero.tagline",
                            defaultValue: "Local AI, no more waiting on your Mac.",
                             this.stopMSRefresh();
                    this.stopOQRefresh();
                }
                if (value === 'bench') {
                    if (!this.benchDeviceInfo) await this.loadBenchDeviceInfo();
                    await this.loadBenchState();
                    await this.loadAccState();
                    await this.loadCtxBenchState();
                }
            },

            applyTabStateFromUrl() {
                const params = new URLSearchParams(window.location.search);
                const mainTab = params.get('tab');
                const settingsTab = params.get('settingsTab');
                const modelsTab = params.get('modelsTab');

                const benchTab = params.get('benchTab');

                this.mainTab = DASHBOARD_MAIN_TABS.has(mainTab) ? mainTab : 'status';
                this.activeTab = DASHBOARD_SETTINGS_TABS.has(settingsTab) ? settingsTab : 'global';
                this.modelsTab = DASHBOARD_MODELS_TABS.has(modelsTab) ? modelsTab : 'manager';
                this.benchTab = DASHBOARD_BENCH_TABS.has(benchTab) ? benchTab : 'throughput';
            },

            syncTabStateToUrl() {
                const url = new URL(window.location.href);
                url.searchParams.set('tab', this.mainTab);

                if (this.mainTab === 'settings') {
                    url.searchParams.set('settingsTab', this.activeTab);
                } else {
                    url.searchParams.delete('settingsTab');
                }

                if (this.mainTab === 'models') {
                    url.searchParams.set('modelsTab', this.modelsTab);
                } else {
                    url.searchParams.delete('modelsTab');
                }

                if (this.mainTab === 'bench') {
                    url.searchParams.set('benchTab', this.benchTab);
                } else {
                    url.searchParams.delete('benchTab');
                }

                window.history.replaceState({}, '', url);
            },

            setMainTab(tab) {
                if (!DASHBOARD_MAIN_TABS.has(tab)) return;
                this.mainTab = tab;
                this.syncTabStateToUrl();
            },

            setSettingsTab(tab) {
                if (!DASHBOARD_SETTINGS_TABS.has(tab)) return;
                this.activeTab = tab;
                this.mainTab = 'settings';
                this.syncTabStateToUrl();
            },

            setModelsTab(tab) {
                if (!DASHBOARD_MODELS_TABS.has(tab)) return;
                this.modelsTab = tab;
                this.mainTab = 'models';
                this.syncTabStateToUrl();
                if (tab === 'quantizer') {
                    this.loadOQModels();
                }
                if (tab === 'uploader') {
                    if (!this.uploadOqModelsLoaded) this.loadUploadOqModels();
                    this.loadUploadTasks();
                }
            },

            async checkForUpdate() {
                try {
                    const resp = await fetch('/admin/api/update-check');
                    if (resp.ok) {
                        const data = await resp.json();
                        this.updateAvailable = data.update_available;
                        this.latestVersion = data.latest_version;
                        this.releaseUrl = data.release_url;
                    }
                } catch (e) {
                    // Silently ignore - not critical
                }
            },

            startUpdateCheckTimer() {
                this._updateCheckTimer = setInterval(() => this.checkForUpdate(), 3600000);
            },

            stopUpdateCheckTimer() {
                if (this._updateCheckTimer) {
                    clearInterval(this._updateCheckTimer);
                    this._updateCheckTimer = null;
                }
            },

            async loadGlobalSettings() {
                try {
                    const response = await fetch('/admin/api/global-settings');
                    if (response.ok) {
                        cons / (split_tiles_m * split_tiles_n);
      const int partitions =
          std::min(std::max(2, next_power_of_two(split_ratio)), 32);
      const int partition_stride = M * N;
      const int gemm_k_iterations = (K / split_bk) / partitions;
      const int partition_size = gemm_k_iterations * split_bk;

      array split(
          {rows, partitions, M, N},
          float32,
          nullptr,
          {});
      split.set_data(allocator::malloc(split.nbytes()));

      const bool mn_aligned = M % split_bm == 0 && N % split_bn == 0;
      const bool k_aligned = K % split_bk == 0;
      std::ostringstream split_name;
      split_name << "omlx_dspark_gemm_splitk_" << type_to_name(lhs)
                 << "_nt" << (transpose_rhs_ ? "true" : "false") << "_MN_"
                 << (mn_aligned ? "taligned" : "naligned") << "_K_"
                 << (k_aligned ? "taligned" : "naligned");

      auto split_kernel = device.get_kernel(split_name.str(), library);
      auto& encoder = metal::get_command_encoder(stream);
      encoder.set_compute_pipeline_state(split_kernel);

      GEMMSpiltKParams params{
          M,
          N,
          K,
          K,
          ldb,
          N,
          split_tiles_n,
          split_tiles_m,
          partitions,
          partition_stride,
          partition_size,
          0,
          gemm_k_iterations};
      const int64_t batch_stride_a = static_cast<int64_t>(M) * K;
      const int64_t batch_stride_b =
          static_cast<int64_t>(rhs.shape(1)) * rhs.shape(2);

      encoder.set_input_array(lhs, 0);
      encoder.set_input_array(rhs, 1);
      encoder.set_output_array(split, 2);
      encoder.set_bytes(params, 3);
      encoder.set_bytes(batch_stride_a, 4);
      encoder.set_bytes(batch_stride_b, 5);
      encoder.dispatch_threadgroups(
          MTL::Size(split_tiles_n, split_tiles_m, rows * partitions),
          MTL::Size(32, split_wn, split_wm));

      const std::string accum_name =
          "omlx_dspark_gemm_splitk_accum_" + type_to_name(output) +
          "_float32";
      auto accum_kernel = device.get_kernel(accum_name, library);
      encoder.set_compute_pipeline_state(accum_kernel);
      encoder.set_input_array(split, 0);
      encoder.set_output_array(output, 1);
      encoder.set_bytes(partitions, 2);
      encoder.set_bytes(partition_stride, 3);
      encoder.set_bytes(N, 4);
      encoder.dispatch_threads(
          MTL::Size(N, M, rows), MTL::Size(32, 8, 1));
      encoder.add_temporary(std::move(split));
      return;
    }

    const bool has_batch = false;
    const bool use_out_source = false;
    const bool do_axpby = false;
    const bool align_m = M % bm == 0;
    const bool align_n = N % bn == 0;
    const bool align_k = K % bk == 0;
    metal::MTLFCList constants = {
        {&has_batch, MTL::DataType::DataTypeBool, 10},
        {&use_out_source, MTL::DataType::DataTypeBool, 100},
        {&do_axpby, MTL::DataType::DataTypeBool, 110},
        {&align_m, MTL::DataType::DataTypeBool, 200},
        {&align_n, MTL::DataType::DataTypeBool, 201},
        {&align_k, MTL::DataType::DataTypeBool, 202},
    };

    std::string base_name = "omlx_dspark_gemm_" + type_to_name(lhs) +
        "_nt" + (transpose_rhs_ ? "true" : "false");
    std::ostringstream hash;
    hash << base_name << "_am" << align_m << "_an" << align_n << "_ak"
         << align_k;

    auto kernel = device.get_kernel(base_name, library, hash.str(), constants);
    auto& encoder = metal::get_command_encoder(stream);
    encoder.set_compute_pipeline_state(kernel);

    constexpr int swizzle_log = 0;
    const int tiles_n = (N + bn - 1) / bn;
    const int tiles_m = (M + bm - 1) / bm;
    GEMMParams params{
        M,
        N,
        K,
        K,
        ldb,
        N,
        tiles_n,
        tiles_m,
        static_cast<int64_t>(M) * K,
        static_cast<int64_t>(rhs.shape(1)) * rhs.shape(2),
        static_cast<int64_t>(M) * N,
        swizzle_log,
        K / bk,
        1};

    encoder.set_input_array(lhs, 0);
    encoder.set_input_array(rhs, 1);
    encoder.set_output_array(output _INKLING_CONTENT_THINKING,
    _INKLING_CONTENT_TEXT,
    _INKLING_CONTENT_XML,
    _INKLING_CONTENT_TOOL_JSON,
    _INKLING_END_MESSAGE,
    _INKLING_END_SAMPLING,
)


def _is_inkling_model(
    model_name: str,
    model_config: dict[str, Any] | None = None,
) -> bool:
    model_type = model_config.get("model_type") if model_config else None
    if model_type in _INKLING_MODEL_TYPES:
        return True
    return "inkling" in model_name.lower()


class _InklingChannelSplitter:
    """Streaming splitter for inkling's channel protocol.

    The assistant turn is a sequence of blocks::

        [<|message_model|>][HEAD]<|content_*|>BODY<|end_message|> ... \
<|content_model_end_sampling|>

    ``HEAD`` only occurs for tool calls (the function name before
    ``<|content_invoke_tool_json|>``). Thinking bodies surface on the
    stream inside oMLX's ``<think>``/``</think>`` markers, text bodies on
    stream+visible, tool JSON is suppressed (parsed at finalize from the
    raw text).
    """

    def __init__(self) -> None:
        self._buffer = ""
        self._channel: str | None = None
        self._head = ""
        self._think_open = False
        self.stopped = False

    def _partial_suffix_len(self, text: str) -> int:
        max_len = min(len(text), max(len(m) for m in _INKLING_MARKERS) - 1)
        for size in range(max_len, 0, -1):
            suffix = text[-size:]
            if any(m.startswith(suffix) for m in _INKLING_MARKERS):
                return size
        return 0

    def _emit_body(self, text: str) -> tuple[str, str]:
        if not text:
            return "", ""
        if self._channel in ("text", "xml"):
            return text, text
        if self._channel == "thinking":
            # Thinking flows to BOTH channels wrapped in <think> markers
            # (minimax pattern): the scheduler accumulates only
            # visible_text into request.output_text, and the API layer
            # extracts reasoning_content from the <think> block there.
            return text, text
        if self._channel == "tool":
            return "", ""
        # Block head: hold until the next marker classifies it.
        self._head += text
        return "", ""

    def _flush_head_as_text(self) -> tuple[str, str]:
        head, self._head = self._head, ""
        if not head:
            return "", ""
        return head, head

    def _handle_marker(self, marker: str) -> tuple[str, str]:
        stream = visible = ""
        if marker == _INKLING_CONTENT_THINKING:
            s, v = self._flush_head_as_text()
            stream += s
            visible += v
            if not self._think_open:
                stream += "<think>"
                visible += "<think>"
                self._think_open = True
            self._channel = "thinking"
        elif marker in (_INKLING_CONTENT_TEXT, _INKLING_CONTENT_XML):
            s, v = self._flush_head_as_text()
            stream += s
            visible += v
            if self._think_open:
                # A text block after an unterminated thinking block still
                # closes the visible thinking span.
                stream += "</think>"
                visible += "</think>"
                self._think_open = False
            self._channel = "text" if marker == _INKLING_CONTENT_TEXT else "xml"
        elif marker == _INKLING_CONTENT_TOOL_JSON:
            # Head was the tool name; the JSON payload is parsed at
            # finalize from the raw text.
            self._head = ""
            self._channel = "tool"
        elif marker == _INKLING_END_MESSAGE:
            if self._channel == "thinking" and self._think_open:
                stream += "</think>"
                visible += "</think>"
                self._think_open = False
            s, v = self._flush_head_as_text()
            stream += s
            visible += v
            self._channel = None
        elif marker == _INKLING_MESSAGE_MODEL:
            s, v = self._flush_head_as_text()
            stream += s
            visible += v
            self._channel = None
        elif   comment: "Tagline shown under the oMLX product name on the About screen hero card"))
                    .font(.omlxText(12))
                    .foregroundStyle(theme.textSecondary)
                Text(String(localized: "about.hero.version",
                            defaultValue: "Version \(version) · build \(build)",
                            comment: "Version + build line on the About screen hero card; placeholders are the bundle short version string and bundle version"))
                    .font(.omlxMono(11))
                    .foregroundStyle(theme.textTertiary)
            }
            Spacer(minLength: 8)
        }
        .padding(18)
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(theme.groupBg)
        .clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
        .overlay(
            RoundedRectangle(cornerRadius: 12, style: .continuous)
                .strokeBorder(theme.groupBorder, lineWidth: 0.5)
        )
        .padding(.horizontal, 14)
        .padding(.bottom, 14)
    }
}

// MARK: - Project section

private struct ProjectSection: View {
    var body: some View {
        SectionHeader(String(localized: "about.section.project",
                             defaultValue: "Project",
                             comment: "Section header above the project links list on the About screen"))

        ListGroup {
            LinkRow(
                label: String(localized: "about.project.github.label",
                              defaultValue: "GitHub Repository",
                              comment: "About screen link row label pointing to the oMLX GitHub repo"),
                sublabel: String(localized: "about.project.github.sub",
                                 defaultValue: "Source, issues, and roadmap",
                                 comment: "Sublabel under the GitHub Repository link on the About screen"),
                icon: "chevron.left.forwardslash.chevron.right",
                url: URL(string: "https://github.com/jundot/omlx")!
            )
            LinkRow(
                label: String(localized: "about.project.releases.label",
                              defaultValue: "Releases",
                              comment: "About screen link row label pointing to GitHub releases"),
                sublabel: String(localized: "about.project.releases.sub",
                                 defaultValue: "Download the latest CLI and macOS app",
                                 comment: "Sublabel under the Releases link on the About screen"),
                icon: "shippingbox",
                url: URL(string: "https://github.com/jundot/omlx/releases")!
            )
            LinkRow(
                label: String(localized: "about.project.docs.label",
                              defaultValue: "Documentation",
                              comment: "About screen link row label pointing to product documentation"),
                sublabel: String(localized: "about.project.docs.sub",
                                 defaultValue: "Setup, model management, integrations",
                                 comment: "Sublabel under the Documentation link on the About screen"),
                icon: "book.closed",
                url: URL(string: "https://github.com/jundot/omlx")!
            )
            LinkRow(
                label: String(localized: "about.project.issue.label",
                              defaultValue: "Report an Issue",
                              comment: "About screen link row label pointing to the GitHub new-issue form"),
                sublabel: String(localized: "about.project.issue.sub",
                                 defaultValue: "Bugs and feature requests on GitHub",
                                 comment: "Sublabel under the Report an Issue link on the About screen"),
                icon: "exclamationmark.bubble",
                url: URL(string: "https://github.com/jundot/omlx/issues/new")!,
                isLast: true
            )
        }
    }
}

// MARK: - License

private struct Lt data = await response.json();
                        // Deep merge to preserve defaults for missing fields
                        // Handle model_dirs: prefer list, fallback to single model_dir
                        const modelDirs = data.model?.model_dirs?.length
                            ? data.model.model_dirs
                            : (data.model?.model_dir ? [data.model.model_dir] : ['']);
                        this.globalSettings = {
                            ...this.globalSettings,
                            ...data,
                            server: { ...this.globalSettings.server, ...data.server },
                            model: { ...this.globalSettings.model, ...data.model, model_dirs: modelDirs },
                            memory: { ...this.globalSettings.memory, ...data.memory },
                            scheduler: { ...this.globalSettings.scheduler, ...data.scheduler },
                            cache: { ...this.globalSettings.cache, ...data.cache },
                            sampling: { ...this.globalSettings.sampling, ...data.sampling },
                            mcp: { ...this.globalSettings.mcp, ...data.mcp },
                            huggingface: { ...this.globalSettings.huggingface, ...data.huggingface },
                            network: { ...this.globalSettings.network, ...data.network },
                            auth: { ...this.globalSettings.auth, ...data.auth },
                            claude_code: { ...this.globalSettings.claude_code, ...data.claude_code },
                            integrations: { ...this.globalSettings.integrations, ...data.integrations },
                            idle_timeout: { ...this.globalSettings.idle_timeout, ...data.idle_timeout },
                            system: { ...this.globalSettings.system, ...data.system },
                        };
                        this.globalSettings.ui = data.ui || { language: 'en' };

                        // Sync idle timeout select value
                        this.idleTimeoutValue = this.globalSettings.idle_timeout?.idle_timeout_seconds != null
                            ? String(this.globalSettings.idle_timeout.idle_timeout_seconds)
                            : '';

                        // Normalize memory guard tier to one of the known values.
                        const validTiers = ['safe', 'balanced', 'aggressive', 'custom'];
                        if (!validTiers.includes(this.globalSettings.memory.memory_guard_tier)) {
                            this.globalSettings.memory.memory_guard_tier = 'balanced';
                        }

                        // Calculate cache percent from stored value (based on total capacity)
                        this.cachePercent = this.parseCacheToPercent(
                            this.globalSettings.cache.ssd_cache_max_size,
                            this.globalSettings.system.ssd_total_bytes
                        );
                        // Sync the cache string value from percent
                        this.updateCacheFromSlider();

                        // Calculate hot cache percent from stored value
                        this.globalSettings.cache.hot_cache_max_size = this.normalizeHotCacheMaxSize(
                            this.globalSettings.cache.hot_cache_max_size
                        );
                        this.hotCachePercent = this.parseHotCacheToPercent(
                            this.globalSettings.cache.hot_cache_max_size,
                            this.globalSettings.system.total_memory_bytes
                        );
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (err) {
                    console.error('Failed to load global settings:', err);
                }
            },

            async saveGlobalSettings() {
                this.saving = true;
                this.saveSuccess = false;
                this.saveError = '';

                // Validate required, 3);
    encoder.set_bytes(params, 4);

    const int swizzle = 1 << swizzle_log;
    const int grid_n = tiles_n * swizzle;
    const int grid_m = (tiles_m + swizzle - 1) / swizzle;
    encoder.dispatch_threadgroups(
        MTL::Size(grid_n, grid_m, rows), MTL::Size(32, wn, wm));
  }

  DEFINE_NAME(OMLXDSparkRowwiseGemm)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    return transpose_rhs_ ==
        static_cast<const DSparkRowwiseGemmPrimitive&>(other).transpose_rhs_;
  }
  auto state() const {
    return std::make_tuple(nullptr, transpose_rhs_);
  }

 private:
  bool transpose_rhs_;
};

class DSparkRingGemmPrimitive : public Primitive {
 public:
  DSparkRingGemmPrimitive(Stream stream, bool transpose_rhs)
      : Primitive(stream), transpose_rhs_(transpose_rhs) {}

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("DSpark physical-ring GEMM has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& stream = this->stream();
    auto& device = metal::device(stream.device);
    const auto& lhs = inputs[0];
    const auto& source = inputs[1];
    const auto& indices = inputs[2];
    auto& output = outputs[0];

    constexpr int M = 64;
    constexpr int ring_size = 128;
    constexpr int head_dim = 512;
    const int rows = lhs.shape(0);
    const int64_t batch_stride_a =
        static_cast<int64_t>(lhs.shape(1)) * lhs.shape(2);
    const int source_ld = source.shape(1);

    output.set_data(allocator::malloc(output.nbytes()));
    auto library = device.get_library("omlx_glm_kernels", current_binary_dir());
    auto& encoder = metal::get_command_encoder(stream);

    if (transpose_rhs_) {
      constexpr int N = ring_size;
      constexpr int K = head_dim;
      constexpr int bm = 32;
      constexpr int bn = 32;
      constexpr int bk = 16;
      constexpr int wm = 2;
      constexpr int wn = 2;
      constexpr int tiles_m = M / bm;
      constexpr int tiles_n = N / bn;
      constexpr int partitions = 4;
      constexpr int partition_stride = M * N;
      constexpr int gemm_k_iterations = 8;
      constexpr int partition_size = gemm_k_iterations * bk;

      array split({rows, partitions, M, N}, float32, nullptr, {});
      split.set_data(allocator::malloc(split.nbytes()));

      const std::string kernel_name =
          "omlx_dspark_ring_scores_" + type_to_name(lhs);
      auto kernel = device.get_kernel(kernel_name, library);
      encoder.set_compute_pipeline_state(kernel);

      GEMMSpiltKParams params{
          M,
          N,
          K,
          K,
          head_dim,
          N,
          tiles_n,
          tiles_m,
          partitions,
          partition_stride,
          partition_size,
          0,
          gemm_k_iterations};

      encoder.set_input_array(lhs, 0);
      encoder.set_input_array(source, 1);
      encoder.set_input_array(indices, 2);
      encoder.set_output_array(split, 3);
      encoder.set_bytes(params, 4);
      encoder.set_bytes(batch_stride_a, 5);
      encoder.set_bytes(source_ld, 6);
      encoder.dispatch_threadgroups(
          MTL::Size(tiles_n, tiles_m, rows * partitions),
          MTL::Size(32, wn, wm));

      const std::string accum_name =
          "omlx_dspark_gemm_splitk_accum_" + type_to_name(output) +
          "_float32";
      auto accum_kernel = device.get_kernel(accum_name, library);
      encoder.set_compute_pipeline_state(accum_kernel);
      encoder.set_input_array(split, 0);
      encoder.set_output_array(output, 1);
      encoder.set_bytes(partitions, 2);
      encoder.set_bytes(partition_stride, 3);
      encoder.set_bytes(N, 4);
      encoder.dispatch_threads(
          MTL::Size(N, M, rows), MTL::Size(32, 8, 1));
      encoder.add_temporary(std::move(split));
      return;
    }

    constexpr int N = head_dim;
    constexpr int K = ring_size;
    constexpr int bm = 64;
    constexpr int bn = 64;
    constexpr int bk = 16;
    constemarker == _INKLING_END_SAMPLING:
            self.stopped = True
            self._channel = None
        return stream, visible

    def feed(self, text: str) -> tuple[str, str]:
        if not text:
            return "", ""
        self._buffer += text
        stream = visible = ""
        while True:
            first_idx = -1
            first_marker = None
            for marker in _INKLING_MARKERS:
                idx = self._buffer.find(marker)
                if idx >= 0 and (first_idx < 0 or idx < first_idx):
                    first_idx = idx
                    first_marker = marker
            if first_marker is None:
                break
            s, v = self._emit_body(self._buffer[:first_idx])
            stream += s
            visible += v
            m_s, m_v = self._handle_marker(first_marker)
            stream += m_s
            visible += m_v
            self._buffer = self._buffer[first_idx + len(first_marker) :]

        keep = self._partial_suffix_len(self._buffer)
        ready = self._buffer[: len(self._buffer) - keep]
        self._buffer = self._buffer[len(self._buffer) - keep :]
        s, v = self._emit_body(ready)
        return stream + s, visible + v

    def finish(self) -> tuple[str, str]:
        stream = visible = ""
        s, v = self._emit_body(self._buffer)
        stream += s
        visible += v
        self._buffer = ""
        s, v = self._flush_head_as_text()
        stream += s
        visible += v
        if self._think_open:
            stream += "</think>"
            visible += "</think>"
            self._think_open = False
        return stream, visible


class InklingOutputParserSession:
    """Parser session for inkling channel output (thinking / text / tool)."""

    _TOOL_RE = None  # compiled lazily

    def __init__(self, tokenizer: Any, model_path: str | None = None):
        import re

        self._tokenizer = tokenizer
        self._raw_text = ""
        self._splitter = _InklingChannelSplitter()
        self._detokenizer = create_streaming_detokenizer(tokenizer, model_path)
        if self._detokenizer is not None:
            self._detokenizer.reset()
        if InklingOutputParserSession._TOOL_RE is None:
            InklingOutputParserSession._TOOL_RE = re.compile(
                re.escape(_INKLING_CONTENT_TOOL_JSON)
                + r"(.*?)(?:"
                + re.escape(_INKLING_END_MESSAGE)
                + r"|"
                + re.escape(_INKLING_END_SAMPLING)
                + r"|\Z)",
                re.S,
            )

    def _decode_token(self, token_id: int) -> str:
        if self._detokenizer is not None:
            self._detokenizer.add_token(token_id)
            return self._detokenizer.last_segment
        try:
            return self._tokenizer.decode([token_id], skip_special_tokens=False)
        except TypeError:
            return self._tokenizer.decode([token_id])

    def process_token(self, token_id: int) -> OutputParserTokenResult:
        if self._splitter.stopped:
            return OutputParserTokenResult(is_stop=True, record_token=False)
        decoded_text = self._decode_token(token_id)
        self._raw_text += decoded_text
        stream_text, visible_text = self._splitter.feed(decoded_text)
        is_stop = self._splitter.stopped
        return OutputParserTokenResult(
            stream_text=stream_text,
            visible_text=visible_text,
            is_stop=is_stop,
            record_token=not is_stop,
        )

    def finalize(self) -> OutputParserFinalizeResult:
        stream_text = ""
        visible_text = ""
        if self._detokenizer is not None and not self._splitter.stopped:
            self._detokenizer.finalize()
            final_text = self._detokenizer.last_segment
            if final_text:
                self._raw_text += final_text
                s, v = self._splitter.feed(final_text)
                stream_text += s
                visible_text += v
        s, v = self._splitter.finish()
        stream_text += s
        visible_text += v

        tool_calls: list[dict[str, str]]icenseSection: View {
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        SectionHeader(String(localized: "about.section.license",
                             defaultValue: "License",
                             comment: "Section header above the license block on the About screen"))

        ListGroup {
            FreeRow(isLast: true) {
                VStack(alignment: .leading, spacing: 6) {
                    HStack(spacing: 6) {
                        Image(systemName: "scale.3d")
                            .font(.system(size: 13))
                            .foregroundStyle(theme.textSecondary)
                        Text(String(localized: "about.license.name",
                                    defaultValue: "Apache License 2.0",
                                    comment: "Name of the open-source license shown on the About screen"))
                            .font(.omlxText(13, weight: .medium))
                            .foregroundStyle(theme.text)
                    }
                    Text(String(localized: "about.license.notice",
                                defaultValue: "Copyright © oMLX contributors. Licensed under the Apache License, Version 2.0. See the LICENSE file in the repository for the full text.",
                                comment: "Copyright + license notice paragraph on the About screen"))
                        .font(.omlxText(11.5))
                        .foregroundStyle(theme.textSecondary)
                        .fixedSize(horizontal: false, vertical: true)
                }
            }
        }
    }
}

// MARK: - Credits

private struct CreditsSection: View {
    @Environment(\.omlxTheme) private var theme

    private struct Credit: Identifiable {
        let id = UUID()
        let name: String
        let role: String
        let url: URL
    }

    private let credits: [Credit] = [
        Credit(
            name: "MLX",
            role: String(localized: "about.credits.mlx.role",
                         defaultValue: "Apple's array framework — the engine behind every model",
                         comment: "About screen Credits row: role/description for the MLX project"),
            url: URL(string: "https://github.com/ml-explore/mlx")!
        ),
        Credit(
            name: "mlx-lm",
            role: String(localized: "about.credits.mlx_lm.role",
                         defaultValue: "Language-model execution + fine-tuning on MLX",
                         comment: "About screen Credits row: role/description for the mlx-lm project"),
            url: URL(string: "https://github.com/ml-explore/mlx-lm")!
        ),
        Credit(
            name: "mlx-vlm",
            role: String(localized: "about.credits.mlx_vlm.role",
                         defaultValue: "Vision-language models on MLX",
                         comment: "About screen Credits row: role/description for the mlx-vlm project"),
            url: URL(string: "https://github.com/Blaizzy/mlx-vlm")!
        ),
        Credit(
            name: "mlx-embeddings",
            role: String(localized: "about.credits.mlx_embeddings.role",
                         defaultValue: "Embedding + reranker models on MLX",
                         comment: "About screen Credits row: role/description for the mlx-embeddings project"),
            url: URL(string: "https://github.com/Blaizzy/mlx-embeddings")!
        ),
        Credit(
            name: "mlx-audio",
            role: String(localized: "about.credits.mlx_audio.role",
                         defaultValue: "Audio (STT / TTS / STS) models on MLX",
                         comment: "About screen Credits row: role/description for the mlx-audio project"),
            url: URL(string: "https://github.com/Blaizzy/mlx-audio")!
        ),
    ]

    var body: some View {
        SectionHeader(String(localized: "about.section.built_on",
                             defaultValue: "Built On",
                             comment: "Section header above the credits list on the About screen"))

        ListGrou fields
                const errors = [];
                const s = this.globalSettings;
                if (!s.server.host) errors.push('Host');
                if (!s.server.port) errors.push('Port');
                if (!s.model.model_dirs || !s.model.model_dirs.some(d => d.trim())) errors.push('Model Directory');
                if (!s.scheduler.max_concurrent_requests) errors.push('Max Concurrent Requests');
                if (!s.scheduler.embedding_batch_size) errors.push('Embedding Batch Size');
                if (!s.cache.ssd_cache_max_size) errors.push('Max Cache Size');
                if (!s.sampling.max_context_window) errors.push('Max Context Window');
                if (!s.sampling.max_tokens) errors.push('Max Tokens');

                if (errors.length > 0) {
                    this.saveError = window.t('js.error.required_fields').replace('{fields}', errors.join(', '));
                    this.saving = false;
                    return;
                }

                // Validate API key if provided
                if (s.auth.api_key) {
                    if (s.auth.api_key.length < 4) {
                        this.saveError = window.t('js.error.api_key_min_length');
                        this.saving = false;
                        return;
                    }
                    if (/\s/.test(s.auth.api_key)) {
                        this.saveError = window.t('js.error.api_key_no_whitespace');
                        this.saving = false;
                        return;
                    }
                }

                try {
                    const response = await fetch('/admin/api/global-settings', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            host: this.globalSettings.server.host,
                            port: this.globalSettings.server.port,
                            log_level: this.globalSettings.server.log_level,
                            sse_keepalive_mode: this.globalSettings.server.sse_keepalive_mode,
                            burst_decode_mode: this.globalSettings.server.burst_decode_mode,
                            preserve_mid_system_cache: this.globalSettings.server.preserve_mid_system_cache,
                            model_dirs: this.globalSettings.model.model_dirs.filter(d => d.trim()),
                            model_fallback: this.globalSettings.model.model_fallback,
                            hide_helper_models: this.globalSettings.model.hide_helper_models,
                            memory_prefill_memory_guard: this.globalSettings.memory.prefill_memory_guard,
                            memory_guard_tier: this.globalSettings.memory.memory_guard_tier,
                            memory_guard_custom_ceiling_gb: this.globalSettings.memory.memory_guard_custom_ceiling_gb,
                            max_concurrent_requests: this.globalSettings.scheduler.max_concurrent_requests,
                            embedding_batch_size: this.globalSettings.scheduler.embedding_batch_size,
                            chunked_prefill: this.globalSettings.scheduler.chunked_prefill,
                            prefill_priority: this.globalSettings.scheduler.prefill_priority,
                            cache_enabled: this.globalSettings.cache.enabled,
                            ssd_cache_dir: this.globalSettings.cache.ssd_cache_dir,
                            ssd_cache_max_size: this.globalSettings.cache.ssd_cache_max_size,
                            hot_cache_max_size: this.normalizeHotCacheMaxSize(
                                this.globalSettings.cache.hot_cache_max_size
                            ),
                            initial_cache_blocks: this.globalSettings.cache.initial_cache_blocks,
                            hot_cache_only: this.globalSettings.cache.hot_cache_only,
                            sampling_max_context_window: this.globalSettings.sampling.max_context_window,
                            saxpr int wm = 1;
    constexpr int wn = 2;
    constexpr int tiles_m = M / bm;
    constexpr int tiles_n = N / bn;
    constexpr int gemm_k_iterations = K / bk;
    constexpr int64_t batch_stride_d = static_cast<int64_t>(M) * N;

    const std::string kernel_name =
        "omlx_dspark_ring_values_" + type_to_name(lhs);
    auto kernel = device.get_kernel(kernel_name, library);
    encoder.set_compute_pipeline_state(kernel);

    GEMMParams params{
        M,
        N,
        K,
        K,
        N,
        N,
        tiles_n,
        tiles_m,
        batch_stride_a,
        0,
        batch_stride_d,
        0,
        gemm_k_iterations,
        1};

    encoder.set_input_array(lhs, 0);
    encoder.set_input_array(source, 1);
    encoder.set_input_array(indices, 2);
    encoder.set_output_array(output, 3);
    encoder.set_bytes(params, 4);
    encoder.set_bytes(batch_stride_a, 5);
    encoder.set_bytes(source_ld, 6);
    encoder.dispatch_threadgroups(
        MTL::Size(tiles_n, tiles_m, rows), MTL::Size(32, wn, wm));
  }

  DEFINE_NAME(OMLXDSparkRingGemm)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    return transpose_rhs_ ==
        static_cast<const DSparkRingGemmPrimitive&>(other).transpose_rhs_;
  }
  auto state() const {
    return std::make_tuple(nullptr, transpose_rhs_);
  }

 private:
  bool transpose_rhs_;
};

} // namespace

mx::array dspark_rowwise_gemm(
    const mx::array& lhs,
    const mx::array& rhs,
    bool transpose_rhs,
    mx::StreamOrDevice s) {
  auto stream = to_stream(s);
  if (!metal::is_available() || stream.device == Device::cpu) {
    throw std::invalid_argument("DSpark rowwise GEMM requires Metal.");
  }
  if (lhs.ndim() != 3 || rhs.ndim() != 3 || lhs.shape(0) != rhs.shape(0) ||
      lhs.shape(1) != 64 || lhs.dtype() != rhs.dtype() ||
      (lhs.dtype() != float16 && lhs.dtype() != bfloat16 &&
       lhs.dtype() != float32) ||
      (lhs.dtype() == float32 && !transpose_rhs) ||
      !lhs.flags().row_contiguous || !rhs.flags().row_contiguous) {
    throw std::invalid_argument("Unsupported DSpark rowwise GEMM layout.");
  }
  const int K = lhs.shape(2);
  if ((transpose_rhs && rhs.shape(2) != K) ||
      (!transpose_rhs && rhs.shape(1) != K)) {
    throw std::invalid_argument("DSpark rowwise GEMM K dimensions differ.");
  }
  const int N = transpose_rhs ? rhs.shape(1) : rhs.shape(2);
  Shape shape{lhs.shape(0), lhs.shape(1), N};
  return array(
      std::move(shape),
      lhs.dtype(),
      std::make_shared<DSparkRowwiseGemmPrimitive>(stream, transpose_rhs),
      std::vector<array>{lhs, rhs});
}

mx::array dspark_ring_gemm(
    const mx::array& lhs,
    const mx::array& source,
    const mx::array& indices,
    bool transpose_rhs,
    mx::StreamOrDevice s) {
  auto stream = to_stream(s);
  if (!metal::is_available() || stream.device == Device::cpu) {
    throw std::invalid_argument("DSpark physical-ring GEMM requires Metal.");
  }
  if (lhs.ndim() != 3 || source.ndim() != 2 || indices.ndim() != 2 ||
      lhs.shape(0) != indices.shape(0) || lhs.shape(0) < 1 ||
      lhs.shape(0) > 6 || lhs.shape(1) != 64 || source.shape(0) < 128 ||
      source.shape(1) != 512 || indices.shape(1) != 128 ||
      lhs.dtype() != source.dtype() ||
      (lhs.dtype() != float16 && lhs.dtype() != bfloat16) ||
      indices.dtype() != uint32 || !lhs.flags().row_contiguous ||
      !source.flags().row_contiguous || !indices.flags().row_contiguous) {
    throw std::invalid_argument("Unsupported DSpark physical-ring GEMM layout.");
  }
  if ((transpose_rhs && lhs.shape(2) != 512) ||
      (!transpose_rhs && lhs.shape(2) != 128)) {
    throw std::invalid_argument("Unsupported DSpark physical-ring GEMM shape.");
  }

  Shape shape{lhs.shape(0), lhs.shape(1), transpose_rhs ? 128 : 512};
  return array(
      std::move(shape),
      lhs.dtype(),
      std::make_shared<DSparkRingGemmPrimitive>(stream, transpose_rhs),
      std::vector<array>{lhs, source, indices});
}

} // namespace omlx::glm_kernels


# ===== FILE: omlx/custom_kernels/glm_moe_dsa/csrc/dspark_qmv.cpp  = []
        for match in InklingOutputParserSession._TOOL_RE.finditer(self._raw_text):
            payload = match.group(1).strip()
            if not payload:
                continue
            try:
                parsed = json.loads(payload)
            except (json.JSONDecodeError, ValueError):
                logger.debug("Inkling tool-call payload not valid JSON")
                continue
            if not isinstance(parsed, dict) or not parsed.get("name"):
                continue
            args = parsed.get("args", {})
            tool_calls.append(
                {
                    "name": str(parsed["name"]),
                    "arguments": json.dumps(
                        args if isinstance(args, dict) else {},
                        ensure_ascii=False,
                        separators=(",", ":"),
                    ),
                }
            )

        return OutputParserFinalizeResult(
            stream_text=stream_text,
            visible_text=visible_text,
            tool_calls=tool_calls,
            finish_reason="tool_calls" if tool_calls else None,
        )


def _create_cohere2_moe_filter():
    try:
        from cohere_melody import PyFilter, PyFilterOptions
    except ImportError:
        return None

    return PyFilter(PyFilterOptions().cmd4().stream_tool_actions())


def _reserialize_cohere_tool_arguments(args: str) -> str:
    if not args:
        return "{}"
    try:
        return json.dumps(
            json.loads(args, strict=False),
            ensure_ascii=False,
            separators=(",", ":"),
        )
    except (json.JSONDecodeError, ValueError):
        return args or "{}"


class Cohere2MoeOutputParserSession:
    """Parser session for Cohere2 MoE / Command-style Melody output."""

    def __init__(self, tokenizer: Any, model_path: str | None = None):
        self._tokenizer = tokenizer
        self._melody = _create_cohere2_moe_filter()
        if self._melody is None:
            raise RuntimeError("cohere_melody is not installed")

        self._detokenizer = create_streaming_detokenizer(tokenizer, model_path)
        if self._detokenizer is not None:
            self._detokenizer.reset()

        self._thinking_started = False
        self._thinking_closed = False
        self._tool_calls: dict[int, dict[str, str]] = {}

    def _decode_token(self, token_id: int) -> str:
        if self._detokenizer is not None:
            self._detokenizer.add_token(token_id)
            return self._detokenizer.last_segment
        try:
            return self._tokenizer.decode([token_id], skip_special_tokens=False)
        except TypeError:
            return self._tokenizer.decode([token_id])

    def _accumulate_tool_calls(self, tool_calls: list[Any]) -> None:
        for tool_call in tool_calls:
            index = int(getattr(tool_call, "index", 0) or 0)
            current = self._tool_calls.setdefault(
                index,
                {"id": "", "name": "", "arguments": ""},
            )
            current["id"] += getattr(tool_call, "id", "") or ""
            current["name"] += getattr(tool_call, "name", "") or ""
            current["arguments"] += getattr(tool_call, "arguments", "") or ""

    def _apply_melody_result(self, result: Any) -> tuple[str, str]:
        stream_text = ""
        visible_text = ""

        reasoning = getattr(result, "reasoning", None)
        if reasoning:
            if not self._thinking_started:
                self._thinking_started = True
                stream_text += "<think>\n"
                visible_text += "<think>\n"
            stream_text += reasoning
            visible_text += reasoning

        content = getattr(result, "content", None)
        if content:
            if self._thinking_started and not self._thinking_closed:
                self._thinking_closed = True
                stream_text += "</think>\n"
                visible_text += "</think>\n"
            stream_text += content
            visible_text += content

        self._accumulate_tool_calls(getattr(result, "tool_calls", []) or []p {
            ForEach(Array(credits.enumerated()), id: \.element.id) { idx, credit in
                LinkRow(
                    label: credit.name,
                    sublabel: credit.role,
                    url: credit.url,
                    isLast: idx == credits.count - 1
                ) {
                    Squircle(systemSymbol: "cpu",
                             size: 26,
                             gradient: SquircleGradient.models)
                }
            }
        }
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/AccuracyBenchScreen.swift =====

// PR 12 — Accuracy Benchmark screen.
//
// Mirrors the "Accuracy" tab from the HTML admin panel
// (omlx/admin/templates/dashboard/_bench.html + dashboard.js accBench*).
// Wires the /admin/api/bench/accuracy/* endpoints — queue add / status /
// remove / results / reset / cancel — onto a stack of sections:
//
//   Configuration         — model picker, batch size segmented, extended-
//                           thinking toggle, and a tap-to-toggle benchmark
//                           grid with inline per-benchmark sample-size
//                           dropdowns. Hard-coded catalog mirrors the HTML
//                           dropdown order.
//
//   Queue                 — visible only when the server reports a running
//                           bench or pending queue items. Shows the active
//                           model (spinner + last-progress message + cancel
//                           button) and each queued entry (model + comma-
//                           separated benchmarks + remove button).
//
//   Error banner          — same shape as QuantizationScreen.
//
//   Results               — accumulating cards keyed by `bench::model`.
//                           Big accuracy %, model badge, optional extended-
//                           thinking pill, correct/total · time. Expandable
//                           per-category breakdown when the server emits it.
//
//   Text export           — collapsible one-liner dump with copy-to-clipboard.
//
// v1 strategy: poll. 2 s while a bench is running OR the queue is non-empty,
// 8 s while idle. Per-question SSE progress isn't surfaced — only block-level
// `message + current/total` from `lastProgress`, which is the same level the
// HTML UI exposes.

import SwiftUI
import AppKit

struct AccuracyBenchScreen: View {
    @Environment(AppServices.self) private var services
    // VM is owned by AppServices so an in-flight queue (or in-progress
    // benchmark) survives screen unloads. Same rationale as
    // ThroughputBenchScreen — see AppServices.accuracyBench.
    @Bindable var vm: AccuracyBenchScreenVM

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            ScreenHeader(
                eyebrow: String(localized: "bench.accuracy.header.eyebrow",
                                defaultValue: "Accuracy Benchmark",
                                comment: "Eyebrow label above the Accuracy Bench screen header"),
                title: String(localized: "bench.accuracy.header.title",
                              defaultValue: "Measure model accuracy",
                              comment: "Accuracy Bench screen primary header"),
                subtitle: String(localized: "bench.accuracy.header.subtitle",
                                 defaultValue: "Queue benchmarks across models. Results accumulate until you reset them. Resume across app launches via the server-side queue.",
                                 comment: "Accuracy Bench screen subtitle explaining queueing behavior")
            )

            ConfigurationSection(
                models: vm.models,
                selectedModelId: $vm.selectedModelId,
                batchSize: $vm.batchSize,
                enableThinking: $vm.enableThinking,
                selectedBenchmarks: $vm.selectedBenchmarks,
                sampleSizes: $vm.sampleSizes,
                isAdding: vm.isAdding,
                canSubmit: vm.canSubmit,
                onSubmit: { vm.addToQueue(clienmpling_max_context_window_policy: this.globalSettings.sampling.max_context_window_policy || null,
                            sampling_max_tokens: this.globalSettings.sampling.max_tokens,
                            sampling_temperature: this.globalSettings.sampling.temperature,
                            sampling_top_p: this.globalSettings.sampling.top_p,
                            sampling_top_k: this.globalSettings.sampling.top_k,
                            sampling_repetition_penalty: this.globalSettings.sampling.repetition_penalty,
                            mcp_config: this.globalSettings.mcp.config_path,
                            hf_cache_enabled: this.globalSettings.huggingface.hf_cache_enabled,
                            network_http_proxy: this.globalSettings.network.http_proxy,
                            network_https_proxy: this.globalSettings.network.https_proxy,
                            network_no_proxy: this.globalSettings.network.no_proxy,
                            network_ca_bundle: this.globalSettings.network.ca_bundle,
                            ...(this.globalSettings.auth.api_key ? { api_key: this.globalSettings.auth.api_key } : {}),
                            skip_api_key_verification: this.globalSettings.auth.skip_api_key_verification,
                            idle_timeout_seconds: this.globalSettings.idle_timeout?.idle_timeout_seconds ?? null,
                        }),
                    });

                    if (response.ok) {
                        const data = await response.json();
                        this.saveSuccess = true;
                        this.saveMessage = data.message || 'Settings saved successfully';
                        // Refresh stats and model list (cache changes unload models)
                        await this.loadStats();
                        await this.loadModels();
                        setTimeout(() => { this.saveSuccess = false; }, 5000);
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        this.saveError = Array.isArray(data.detail) ? data.detail.map(e => (e && typeof e === 'object') ? (e.msg || JSON.stringify(e)) : String(e)).join(', ') : (data.detail || window.t('js.error.save_settings_failed'));
                        // Reload settings to revert to server values
                        await this.loadGlobalSettings();
                    }
                } catch (err) {
                    console.error('Failed to save global settings:', err);
                    this.saveError = window.t('js.error.save_settings_failed');
                    // Reload settings to revert to server values
                    await this.loadGlobalSettings();
                } finally {
                    this.saving = false;
                }
            },

            // Sub key management
            generateSubKey() {
                const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
                const rand = Array.from(crypto.getRandomValues(new Uint8Array(16)))
                    .map(b => chars[b % chars.length]).join('');
                this.newSubKeyValue = 'omlx-' + rand;
                this.showNewSubKey = true;
            },

            async createSubKey() {
                this.subKeyError = '';
                if (!this.newSubKeyValue || this.newSubKeyValue.length < 4) {
                    this.subKeyError = window.t('js.error.api_key_min_length');
                    return;
                }
                if (/\s/.test(this.newSubKeyValue)) {
                    this.subKeyError = window.t('js.error.api_key_no_whitespace');
                    return;
                }
                try {
                    const response = await fetch('/admin/api/sub-keys', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ key: this.newSubKeyVal=====

#include "dspark_qmv.h"

#include <dlfcn.h>
#include <filesystem>
#include <sstream>

#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/metal.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"

namespace omlx::glm_kernels {

namespace {

using namespace mlx::core;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error("Unable to locate DSpark QMV kernel binary.");
    }
    return std::filesystem::path(info.dli_fname).parent_path().string();
  }();
  return binary_dir;
}

struct DSparkQMVParams {
  int K;
  int N;
};

class DSparkExactMXFP8QMVPairPrimitive : public Primitive {
 public:
  explicit DSparkExactMXFP8QMVPairPrimitive(Stream stream) : Primitive(stream) {}

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("DSpark exact MXFP8 QMV pair has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& stream = this->stream();
    auto& device = metal::device(stream.device);
    const auto& input = inputs[0];
    const auto& weight_a = inputs[1];
    const auto& scales_a = inputs[2];
    const auto& weight_b = inputs[3];
    const auto& scales_b = inputs[4];
    auto& output = outputs[0];

    const int rows = input.shape(0);
    const int K = input.shape(1);
    const int N = scales_a.shape(0);
    output.set_data(allocator::malloc(output.nbytes()));

    std::ostringstream name;
    name << "omlx_dspark_exact_mxfp8_qmv_pair_" << type_to_name(input)
         << "_m" << rows;
    auto library = device.get_library("omlx_glm_kernels", current_binary_dir());
    auto kernel = device.get_kernel(name.str(), library);
    auto& encoder = metal::get_command_encoder(stream);
    encoder.set_compute_pipeline_state(kernel);
    encoder.set_input_array(input, 0);
    encoder.set_input_array(weight_a, 1);
    encoder.set_input_array(scales_a, 2);
    encoder.set_input_array(weight_b, 3);
    encoder.set_input_array(scales_b, 4);
    encoder.set_output_array(output, 5);
    DSparkQMVParams params{K, N};
    encoder.set_bytes(params, 6);
    encoder.dispatch_threadgroups(
        MTL::Size(1, N / 8, 2), MTL::Size(32, 2, 1));
  }

  DEFINE_NAME(OMLXDSparkExactMXFP8QMVPair)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& /* other */) const override {
    return true;
  }
  auto state() const {
    return std::make_tuple(nullptr);
  }
};

} // namespace

array dspark_exact_mxfp8_qmv_pair(
    const array& input,
    const array& weight_a,
    const array& scales_a,
    const array& weight_b,
    const array& scales_b,
    StreamOrDevice s) {
  auto stream = to_stream(s);
  if (!metal::is_available() || stream.device == Device::cpu) {
    throw std::invalid_argument("DSpark exact MXFP8 QMV pair requires Metal.");
  }
  if (input.ndim() != 2 || input.shape(0) < 2 || input.shape(0) > 6 ||
      (input.dtype() != float16 && input.dtype() != bfloat16) ||
      !input.flags().row_contiguous || weight_a.ndim() != 2 ||
      weight_b.ndim() != 2 || scales_a.ndim() != 2 || scales_b.ndim() != 2 ||
      weight_a.dtype() != uint32 || weight_b.dtype() != uint32 ||
      scales_a.dtype() != uint8 || scales_b.dtype() != uint8 ||
      weight_a.shape() != weight_b.shape() ||
      scales_a.shape() != scales_b.shape() ||
      !weight_a.flags().row_contiguous || !weight_b.flags().row_contiguous ||
      !scales_a.flags().row_contiguous || !scales_b.flags().row_contiguous) {
    throw std::invalid_argument("Unsupported DSpark exact MXFP8 QMV pair layout.");
  }

  const int K = input.shape(1);
  const int N = scales_a.shape(0);
  if (K % 512 != 0 || N % 8 != 0 || weight_a.shape(0) != N ||
      weight_a.shape(1) * 4 != K || scales_a.shape(1) * 32 != K) {
    throw std::invalid_argument("Invalid DSpark exact MXFP8 QMV pair shape.");
  }

  Shape shape{2, input.shape(0), N};
  return array(
   )
        return stream_text, visible_text

    def process_token(self, token_id: int) -> OutputParserTokenResult:
        decoded_text = self._decode_token(token_id)
        if not decoded_text:
            return OutputParserTokenResult(record_token=True)

        result = self._melody.write_decoded(decoded_text)
        stream_text, visible_text = self._apply_melody_result(result)
        return OutputParserTokenResult(
            stream_text=stream_text,
            visible_text=visible_text,
            record_token=True,
        )

    def finalize(self) -> OutputParserFinalizeResult:
        stream_text = ""
        visible_text = ""

        if self._detokenizer is not None:
            self._detokenizer.finalize()
            final_text = self._detokenizer.last_segment
            if final_text:
                result = self._melody.write_decoded(final_text)
                s_text, v_text = self._apply_melody_result(result)
                stream_text += s_text
                visible_text += v_text

        result = self._melody.flush_partials()
        s_text, v_text = self._apply_melody_result(result)
        stream_text += s_text
        visible_text += v_text

        if self._thinking_started and not self._thinking_closed:
            self._thinking_closed = True
            stream_text += "</think>\n"
            visible_text += "</think>\n"

        tool_calls = [
            {
                "id": value["id"],
                "name": value["name"],
                "arguments": _reserialize_cohere_tool_arguments(value["arguments"]),
            }
            for _, value in sorted(self._tool_calls.items())
            if value["name"]
        ]

        return OutputParserFinalizeResult(
            stream_text=stream_text,
            visible_text=visible_text,
            tool_calls=tool_calls,
            finish_reason="tool_calls" if tool_calls else None,
        )


def detect_output_parser(
    model_name: str,
    tokenizer: Any,
    model_config: dict[str, Any] | None = None,
    model_path: str | None = None,
) -> OutputParserFactory | None:
    """Detect a protocol-specific output parser for the model, if needed.

    ``model_name`` drives detection (string matching) and may be a display
    id rather than a directory since #2178. Pass ``model_path`` when the
    filesystem path is available so parser sessions can locate
    tokenizer.json for their streaming detokenizers.
    """
    session_model_path = model_path or model_name

    if is_harmony_model(model_name, model_config):
        temp_parser = HarmonyStreamingParser(tokenizer)
        return OutputParserFactory(
            kind="harmony",
            create_session=lambda session_tokenizer: HarmonyOutputParserSession(
                session_tokenizer,
                model_path=session_model_path,
            ),
            stop_token_ids=temp_parser.get_stop_token_ids(),
            thinking_end_text="<|end|>",
            thinking_end_trailing_text="<|start|>assistant<|channel|>final<|message|>",
        )

    if is_gemma4_model(model_name, model_config):
        from .gemma4 import (
            _CLOSE_MARKER,
            _OPEN_MARKER_BARE,
            _TOOL_RESPONSE_CLOSE,
            _TOOL_RESPONSE_OPEN,
            _TURN_END_MARKER,
            Gemma4OutputParserSession,
        )

        return OutputParserFactory(
            kind="gemma4",
            create_session=lambda session_tokenizer: Gemma4OutputParserSession(
                session_tokenizer,
                model_path=session_model_path,
            ),
            stop_token_ids=set(),
            thinking_end_text="<channel|>",
            protocol_marker_texts=(
                _OPEN_MARKER_BARE,
                _CLOSE_MARKER,
                _TURN_END_MARKER,
                _TOOL_RESPONSE_OPEN,
                _TOOL_RESPONSE_CLOSE,
            ),
        )

    if _is_deepseek_v4_model(model_name, tokenizer, model_config):
        return OutputParserFactory(
            kind="deepseek_v4",
            create_session=lambda session_tokenizer: DeepSeekV4Outpt: services.client) }
            )

            QueueSection(
                status: vm.status,
                onCancel: { vm.cancelRunning(client: services.client) },
                onRemove: { idx in vm.removeFromQueue(client: services.client, index: idx) }
            )

            MessageBanner(error: vm.lastError)

            ResultsSection(
                results: vm.results,
                onClear: { vm.resetResults(client: services.client) }
            )

            if !vm.results.isEmpty {
                TextExportSection(results: vm.results)
            }
        }
        // `start()` is idempotent: refreshes models + polls once, then
        // restarts the poll loop (which cancels its predecessor). The
        // poll task continues across screen unloads since AppServices
        // owns the VM, so we don't tear it down on disappear.
        .task { await vm.start(client: services.client) }
    }
}

// MARK: - Benchmark catalog (mirrors the HTML dropdown order/labels)

struct BenchmarkCatalogEntry: Hashable, Identifiable {
    let key: String
    let displayName: String
    let category: String
    var id: String { key }
}

private let benchmarkCatalog: [BenchmarkCatalogEntry] = {
    let knowledge = String(localized: "bench.accuracy.category.knowledge",
                           defaultValue: "Knowledge",
                           comment: "Accuracy bench catalog category: knowledge benchmarks")
    let reasoning = String(localized: "bench.accuracy.category.reasoning",
                           defaultValue: "Reasoning",
                           comment: "Accuracy bench catalog category: reasoning benchmarks")
    let math = String(localized: "bench.accuracy.category.math",
                      defaultValue: "Math",
                      comment: "Accuracy bench catalog category: math benchmarks")
    let code = String(localized: "bench.accuracy.category.code",
                      defaultValue: "Code",
                      comment: "Accuracy bench catalog category: code benchmarks")
    let safety = String(localized: "bench.accuracy.category.safety",
                        defaultValue: "Safety",
                        comment: "Accuracy bench catalog category: safety benchmarks")
    // Benchmark display names are proper nouns (dataset names) shared with
    // the HTML admin; only the language-tag suffixes are translated.
    return [
        .init(key: "mmlu",          displayName: "MMLU",          category: knowledge),
        .init(key: "mmlu_pro",      displayName: "MMLU-Pro",      category: knowledge),
        .init(key: "kmmlu",
              displayName: String(localized: "bench.accuracy.dataset.kmmlu",
                                  defaultValue: "KMMLU (Korean)",
                                  comment: "Accuracy bench display name with language tag"),
              category: knowledge),
        .init(key: "cmmlu",
              displayName: String(localized: "bench.accuracy.dataset.cmmlu",
                                  defaultValue: "CMMLU (Chinese)",
                                  comment: "Accuracy bench display name with language tag"),
              category: knowledge),
        .init(key: "jmmlu",
              displayName: String(localized: "bench.accuracy.dataset.jmmlu",
                                  defaultValue: "JMMLU (Japanese)",
                                  comment: "Accuracy bench display name with language tag"),
              category: knowledge),
        .init(key: "hellaswag",     displayName: "HellaSwag",     category: reasoning),
        .init(key: "truthfulqa",    displayName: "TruthfulQA",    category: reasoning),
        .init(key: "arc_challenge", displayName: "ARC-Challenge", category: reasoning),
        .init(key: "winogrande",    displayName: "WinoGrande",    category: reasoning),
        .init(key: "gsm8k",         displayName: "GSM8K",         category: math),
        .init(key: "mathqa",        displayName: "MathQA",        category: math),
        .init(key: "humaneval",     displayName: "HumanEval",     category: code),
 ue, name: this.newSubKeyName }),
                    });
                    if (response.ok) {
                        this.newSubKeyValue = '';
                        this.newSubKeyName = '';
                        this.showNewSubKeyForm = false;
                        this.showNewSubKey = false;
                        await this.loadGlobalSettings();
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        this.subKeyError = data.detail || window.t('js.error.save_settings_failed');
                    }
                } catch (err) {
                    this.subKeyError = window.t('js.error.save_settings_failed');
                }
            },

            async deleteSubKey(key) {
                if (!confirm(window.t('settings.auth.sub_keys_delete_confirm'))) return;
                try {
                    const response = await fetch('/admin/api/sub-keys', {
                        method: 'DELETE',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ key }),
                    });
                    if (response.ok) {
                        await this.loadGlobalSettings();
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (err) {
                    console.error('Failed to delete sub key:', err);
                }
            },

            async loadModels() {
                this.loadingModels = true;
                try {
                    const response = await fetch('/admin/api/models');
                    if (response.ok) {
                        const data = await response.json();
                        this.models = data.models || [];
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (err) {
                    console.error('Failed to load models:', err);
                } finally {
                    this.loadingModels = false;
                }
            },

            async reloadModels() {
                if (this.reloading) return;
                this.reloading = true;
                try {
                    const response = await fetch('/admin/api/reload', { method: 'POST' });
                    if (response.ok) {
                        await Promise.all([this.loadModels(), this.loadHFModels()]);
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        alert(data.detail || window.t('js.error.reload_failed'));
                    }
                } catch (err) {
                    console.error('Failed to reload models:', err);
                    alert(window.t('js.error.reload_failed'));
                } finally {
                    this.reloading = false;
                }
            },

            async updateModelSetting(modelId, field, value) {
                try {
                    const response = await fetch(`/admin/api/models/${encodeURIComponent(modelId)}/settings`, {
                        method: 'PUT',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ [field]: value }),
                    });

                    if (response.ok) {
                        if (field === 'is_default' && value === true) {
                            this.models.forEach(m => { m.is_default = (m.id === modelId); });
                        } else if (field === 'is_pinned') {
                            const model = this.models.find(m => m.id === modelId);
                            if (model) model.pinned = value;
                        } else if (field === 'is_hidden') {
         std::move(shape),
      input.dtype(),
      std::make_shared<DSparkExactMXFP8QMVPairPrimitive>(stream),
      std::vector<array>{input, weight_a, scales_a, weight_b, scales_b});
}

} // namespace omlx::glm_kernels


# ===== FILE: omlx/custom_kernels/glm_moe_dsa/csrc/exact_block_attention.cpp =====

#include "exact_block_attention.h"

#include <dlfcn.h>
#include <filesystem>
#include <sstream>

#include "mlx/backend/common/utils.h"
#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/kernels/steel/attn/params.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"
#include "mlx/utils.h"

namespace omlx::glm_kernels {

namespace {

using namespace mlx::core;
using namespace mlx::steel;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error("Unable to get omlx_glm_kernels binary dir.");
    }
    return std::filesystem::path(info.dli_fname).parent_path().string();
  }();
  return binary_dir;
}

inline int64_t bcast_stride(const array& a, int axis) {
  return a.shape(axis) == 1 ? 0 : a.strides(axis);
}

bool last_dim_contiguous(const array& arr) {
  return arr.strides(-1) == 1;
}

class GlmDsaExactBlockAttentionPrimitive : public Primitive {
 public:
  GlmDsaExactBlockAttentionPrimitive(Stream stream, float scale, bool causal)
      : Primitive(stream), scale_(scale), causal_(causal) {}

  static bool unsupported(
      const array& q,
      const array& k,
      const array& v,
      const array& block_mask,
      const array& block_token_mask,
      bool causal,
      Stream s) {
    if (s.device == Device::cpu || !causal) {
      return true;
    }
    if (q.dtype() != k.dtype() || q.dtype() != v.dtype()) {
      return true;
    }
    if (q.dtype() != float16 && q.dtype() != bfloat16) {
      return true;
    }
    if (q.ndim() != 4 || k.ndim() != 4 || v.ndim() != 4 ||
        block_mask.ndim() != 4 || block_token_mask.ndim() != 4) {
      return true;
    }
    if (!last_dim_contiguous(q) || !last_dim_contiguous(k) ||
        !last_dim_contiguous(v) || !last_dim_contiguous(block_mask) ||
        !last_dim_contiguous(block_token_mask)) {
      return true;
    }
    if (q.shape(0) != k.shape(0) || q.shape(0) != v.shape(0) ||
        k.shape(0) != v.shape(0) || q.shape(1) % k.shape(1) != 0 ||
        k.shape(1) != v.shape(1) || k.shape(2) != v.shape(2) ||
        q.shape(3) != k.shape(3) || q.shape(3) != v.shape(3) ||
        q.shape(3) != 256) {
      return true;
    }
    if (block_mask.dtype() != bool_ || block_token_mask.dtype() != uint32) {
      return true;
    }

    const int qL = q.shape(2);
    const int kL = k.shape(2);
    const int q_blocks16 = (qL + 15) / 16;
    const int q_blocks32 = (qL + 31) / 32;
    const int k_blocks8 = (kL + 7) / 8;
    const int k_blocks16 = (kL + 15) / 16;
    const bool q_block_ok =
        block_mask.shape(-2) == q_blocks16 || block_mask.shape(-2) == q_blocks32;
    const bool k_block_ok = block_mask.shape(-1) == k_blocks8 ||
        block_mask.shape(-1) == k_blocks16;
    if (!q_block_ok || !k_block_ok ||
        block_token_mask.shape(-2) != qL ||
        block_token_mask.shape(-1) != block_mask.shape(-1)) {
      return true;
    }
    if ((block_mask.shape(0) != 1 && block_mask.shape(0) != q.shape(0)) ||
        (block_mask.shape(1) != 1 && block_mask.shape(1) != q.shape(1)) ||
        (block_token_mask.shape(0) != 1 &&
         block_token_mask.shape(0) != q.shape(0)) ||
        (block_token_mask.shape(1) != 1 &&
         block_token_mask.shape(1) != q.shape(1))) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("GlmDsaExactBlockAttentionPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);

    const auto& q = inputs[0];
   utParserSession(
                session_tokenizer,
                model_path=session_model_path,
            ),
            stop_token_ids=set(),
            protocol_marker_texts=(
                _DEEPSEEK_V4_TOOL_CALL_START,
                _DEEPSEEK_V4_TOOL_CALL_END,
            ),
        )

    if _is_cohere2_moe_model(model_name, model_config):
        if _create_cohere2_moe_filter() is None:
            logger.warning(
                "cohere_melody is not installed; Cohere2 MoE output parser "
                "is disabled for %s",
                model_name,
            )
            return None

        return OutputParserFactory(
            kind="cohere2_moe",
            create_session=lambda session_tokenizer: Cohere2MoeOutputParserSession(
                session_tokenizer,
                model_path=session_model_path,
            ),
            stop_token_ids=set(),
            thinking_end_text="</think>",
        )

    if _is_inkling_model(model_name, model_config):
        inkling_stop_ids = set()
        end_sampling_id = _token_id_for_text(tokenizer, _INKLING_END_SAMPLING)
        if end_sampling_id is not None:
            inkling_stop_ids.add(end_sampling_id)

        return OutputParserFactory(
            kind="inkling",
            create_session=lambda session_tokenizer: InklingOutputParserSession(
                session_tokenizer,
                model_path=session_model_path,
            ),
            stop_token_ids=inkling_stop_ids,
            thinking_start_text=_INKLING_CONTENT_THINKING,
            thinking_start_output_text="<think>\n",
            thinking_end_text=_INKLING_END_MESSAGE,
            thinking_end_trailing_text=(
                _INKLING_MESSAGE_MODEL + _INKLING_CONTENT_TEXT
            ),
            protocol_marker_texts=_INKLING_MARKERS,
        )

    if _is_minimax_m3_model(model_name, model_config):
        minimax_stop_ids = set()
        eos_id = _token_id_for_text(tokenizer, _MINIMAX_EOS_TOKEN)
        if eos_id is not None:
            minimax_stop_ids.add(eos_id)

        return OutputParserFactory(
            kind="minimax_m3",
            create_session=lambda session_tokenizer: MiniMaxM3OutputParserSession(
                session_tokenizer,
                model_path=session_model_path,
            ),
            stop_token_ids=minimax_stop_ids,
            thinking_start_text=_MINIMAX_THINK_START,
            thinking_start_output_text="<think>\n",
            thinking_end_text=_MINIMAX_THINK_END,
            protocol_marker_texts=(
                _MINIMAX_THINK_START,
                _MINIMAX_THINK_END,
                _MINIMAX_TOOL_CALL_START,
                _MINIMAX_TOOL_CALL_END,
            ),
        )

    return None


def detect_message_extractor(
    model_name: str,
    model_config: dict[str, Any] | None = None,
) -> Callable:
    """Return the appropriate message extractor function for the model.

    The returned callable has the signature::

        extractor(messages, max_tool_result_tokens=None, tokenizer=None) -> list[dict]

    This mirrors how ``detect_output_parser`` decouples model-specific
    knowledge from the server layer — the engine stores the extractor at
    load time and the server just calls ``engine.message_extractor(...)``.
    """
    if is_harmony_model(model_name, model_config):
        from ..api.utils import extract_harmony_messages

        return extract_harmony_messages

    if is_gemma4_model(model_name, model_config):
        from .gemma4 import extract_gemma4_messages

        return extract_gemma4_messages

    # Default: caller decides between extract_text_content and
    # extract_multimodal_content based on engine type (VLM vs text).
    return None


# ===== FILE: omlx/admin/__init__.py =====

# SPDX-License-Identifier: Apache-2.0
"""Admin panel for oMLX server configuration."""

from .auth import create_session_token, require_admin, verify_session
from .routes import router as admin_router, set_admin_getters, set_hf_downloader

__all__ = [
    "admin_router",
    "create_session_token",
    "requi       .init(key: "mbpp",          displayName: "MBPP",          category: code),
        .init(key: "livecodebench", displayName: "LiveCodeBench", category: code),
        .init(key: "bbq",           displayName: "BBQ",           category: safety),
        .init(key: "safetybench",   displayName: "SafetyBench",   category: safety),
    ]
}()

private let sampleSizeOptions: [(Int, String)] = [
    (0,    String(localized: "bench.accuracy.sample_size.full",
                  defaultValue: "Full",
                  comment: "Sample-size dropdown option: full dataset")),
    (50,   "50"),
    (100,  "100"),
    (200,  "200"),
    (500,  "500"),
    (1000, "1000"),
]

private let batchSizeOptions: [(Int, String)] = [
    (1, "1"), (2, "2"), (4, "4"), (8, "8"), (16, "16"), (32, "32"),
]

// MARK: - Configuration

private struct ConfigurationSection: View {
    let models: [ModelDTO]
    @Binding var selectedModelId: String
    @Binding var batchSize: Int
    @Binding var enableThinking: Bool
    @Binding var selectedBenchmarks: Set<String>
    @Binding var sampleSizes: [String: Int]
    let isAdding: Bool
    let canSubmit: Bool
    let onSubmit: () -> Void

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        SectionHeader(
            String(localized: "bench.accuracy.section.configuration",
                   defaultValue: "Configuration",
                   comment: "Section header for the Accuracy Bench configuration block"),
            subtitle: subtitleText
        )

        ListGroup {
            Row(label: String(localized: "bench.accuracy.row.model.label",
                              defaultValue: "Model",
                              comment: "Row label for the Accuracy Bench model picker"),
                sublabel: String(localized: "bench.accuracy.row.model.sub",
                                 defaultValue: "Loaded models are listed first",
                                 comment: "Sublabel under the Accuracy Bench model picker")) {
                Popup(
                    selection: $selectedModelId,
                    width: 320,
                    options: modelOptions
                )
            }

            Row(
                label: String(localized: "bench.accuracy.row.batch_size.label",
                              defaultValue: "Batch size",
                              comment: "Row label for the Accuracy Bench batch-size selector"),
                sublabel: String(localized: "bench.accuracy.row.batch_size.sub",
                                 defaultValue: "Higher batches finish faster but use more memory",
                                 comment: "Sublabel under the Accuracy Bench batch-size selector")
            ) {
                Segmented(selection: $batchSize, options: batchSizeOptions)
            }

            Row(
                label: String(localized: "bench.accuracy.row.thinking.label",
                              defaultValue: "Extended thinking",
                              comment: "Row label for the Accuracy Bench extended-thinking toggle"),
                sublabel: String(localized: "bench.accuracy.row.thinking.sub",
                                 defaultValue: "Enable per-question reasoning traces (slower)",
                                 comment: "Sublabel under the Accuracy Bench extended-thinking toggle")
            ) {
                Toggle("", isOn: $enableThinking).labelsHidden().toggleStyle(.switch)
            }

            FreeRow {
                VStack(alignment: .leading, spacing: 8) {
                    HStack(spacing: 6) {
                        Text(String(localized: "bench.accuracy.benchmarks.title",
                                    defaultValue: "Benchmarks",
                                    comment: "Inline label above the Accuracy Bench benchmark grid"))
                            .font(.omlxText(13, weight: .medium))
                            .foregroundStyle(theme.text)
                        Text(benchmarksSubtitle)
                            .font(.omlxText(11.5))
                                      const model = this.models.find(m => m.id === modelId);
                            if (model) model.is_hidden = value;
                        } else if (field === 'is_favorite') {
                            const model = this.models.find(m => m.id === modelId);
                            if (model) model.is_favorite = value;
                        }
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        alert(data.detail || window.t('js.error.update_model_setting_failed'));
                        await this.loadModels();
                    }
                } catch (err) {
                    console.error('Failed to update model setting:', err);
                    alert(window.t('js.error.update_model_setting_failed'));
                    await this.loadModels();
                }
            },

            async loadModel(modelId) {
                const model = this.models.find(m => m.id === modelId);
                if (model) model.is_loading = true;
                try {
                    const response = await fetch(`/admin/api/models/${encodeURIComponent(modelId)}/load`, {
                        method: 'POST',
                    });
                    if (response.ok) {
                        await this.loadModels();
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        alert(data.detail || window.t('js.error.load_model_failed'));
                        await this.loadModels();
                    }
                } catch (err) {
                    console.error('Failed to load model:', err);
                    alert(window.t('js.error.load_model_failed'));
                    await this.loadModels();
                }
            },

            async unloadModel(modelId) {
                try {
                    const response = await fetch(`/admin/api/models/${encodeURIComponent(modelId)}/unload`, {
                        method: 'POST',
                    });
                    if (response.ok) {
                        const model = this.models.find(m => m.id === modelId);
                        if (model) model.loaded = false;
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        alert(data.detail || window.t('js.error.unload_model_failed'));
                    }
                    await this.loadModels();
                } catch (err) {
                    console.error('Failed to unload model:', err);
                    alert(window.t('js.error.unload_model_failed'));
                    await this.loadModels();
                }
            },

            // ===== Profiles / Templates =====
            formValuesForProfile() {
                const ms = this.modelSettings;
                const out = {};
                const isDiffusion = !!ms.is_diffusion_model;

                for (const k of this.profileFields.universal.concat(this.profileFields.model_specific)) {
                    if (k === 'chat_template_kwargs' || k === 'forced_ct_kwargs') continue;  // handle below
                    if (isDiffusion && this.isDiffusionUnsupportedProfileField(k)) continue;
                    if (k === 'thinking_budget_enabled') {
                        if (ms.enableThinkingBudget) out.thinking_budget_enabled = true;
                        continue;
                    }
                    if (k === 'thinking_budget_tokens') {
                        if (ms.enableThinkingBudget && ms.thinking_budget_tokens) {
                            out.thinking_budget_tokens = Number(ms.thinking_budget_tokens);
                        }
                     const auto& k = inputs[1];
    const auto& v = inputs[2];
    const auto& block_mask = inputs[3];
    const auto& block_token_mask = inputs[4];
    auto& o = outputs[0];

    int wm = 4;
    constexpr int wn = 1;
    const int bd = q.shape(-1);
    int bk = block_token_mask.shape(-1) == (k.shape(2) + 7) / 8 ? 8 : 16;
    int bq = 32;
    if (block_mask.shape(-2) == (q.shape(2) + 15) / 16) {
      bq = 16;
      wm = 2;
    }

    const int B = q.shape(0);
    const int H = q.shape(1);
    const int qL = q.shape(2);
    const int kL = k.shape(2);
    const int gqa_factor = q.shape(1) / k.shape(1);

    const bool align_Q = (qL % bq) == 0;
    const bool align_K = (kL % bk) == 0;
    const bool has_mask = false;
    const bool has_sinks = false;
    const bool has_block_mask = true;
    const bool has_block_token_mask = true;
    const bool has_block_indices = false;
    const bool do_causal = causal_;

    metal::MTLFCList func_consts = {
        {&align_Q, MTL::DataType::DataTypeBool, 200},
        {&align_K, MTL::DataType::DataTypeBool, 201},
        {&has_mask, MTL::DataType::DataTypeBool, 300},
        {&do_causal, MTL::DataType::DataTypeBool, 301},
        {&has_sinks, MTL::DataType::DataTypeBool, 302},
        {&has_block_mask, MTL::DataType::DataTypeBool, 303},
        {&has_block_token_mask, MTL::DataType::DataTypeBool, 304},
        {&has_block_indices, MTL::DataType::DataTypeBool, 305}};

    std::string base_name;
    concatenate(
        base_name,
        "omlx_glm_exact_attention_",
        type_to_name(q),
        "_bq",
        bq,
        "_bk",
        bk,
        "_bd",
        bd,
        "_wm",
        wm,
        "_wn",
        wn,
        "_mask",
        type_to_name(q));

    std::string hash_name;
    concatenate(
        hash_name,
        base_name,
        "_align_Q_",
        (align_Q ? 't' : 'n'),
        "_align_K_",
        (align_K ? 't' : 'n'),
        "_has_mask_n_do_causal_",
        (do_causal ? 't' : 'n'),
        "_has_sinks_n_has_block_mask_t_has_block_token_mask_t_has_block_indices_n");

    int64_t str_oD = 1;
    int64_t str_oH = o.shape(3);
    int64_t str_oL = o.shape(1) * str_oH;
    int64_t str_oB = o.shape(2) * str_oL;
    size_t data_size = o.shape(0) * str_oB;
    array::Flags flags{
        /* bool contiguous = */ 1,
        /* bool row_contiguous = */ 0,
        /* bool col_contiguous = */ 0,
    };
    o.set_data(
        allocator::malloc(o.nbytes()),
        data_size,
        {str_oB, str_oH, str_oL, str_oD},
        flags);

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto& compute_encoder = metal::get_command_encoder(s);
    auto kernel = d.get_kernel(base_name, lib, hash_name, func_consts);
    compute_encoder.set_compute_pipeline_state(kernel);

    const int NQ = (qL + bq - 1) / bq;
    const int NK = (kL + bk - 1) / bk;
    const int NQ_aligned = qL / bq;
    const int NK_aligned = kL / bk;

    AttnParams params{
        /* int B = */ B,
        /* int H = */ H,
        /* int D = */ bd,
        /* int qL = */ qL,
        /* int kL = */ kL,
        /* int gqa_factor = */ gqa_factor,
        /* float scale = */ scale_,
        /* int NQ = */ NQ,
        /* int NK = */ NK,
        /* int NQ_aligned = */ NQ_aligned,
        /* int NK_aligned = */ NK_aligned,
        /* int qL_rem = */ (qL - NQ_aligned * bq),
        /* int kL_rem = */ (kL - NK_aligned * bk),
        /* int qL_off = */ (kL - qL),
        /* int64_t Q_strides[3] = */ {q.strides(0), q.strides(1), q.strides(2)},
        /* int64_t K_strides[3] = */ {k.strides(0), k.strides(1), k.strides(2)},
        /* int64_t V_strides[3] = */ {v.strides(0), v.strides(1), v.strides(2)},
        /* int64_t O_strides[3] = */ {o.strides(0), o.strides(1), o.strides(2)}};
    AttnBlockMaskParams block_mask_params{/* int64_t BM_strides[3] = */ {
        bcast_stride(block_mask, 0),
        bcast_stride(block_mask, 1),
        bcast_stride(block_mask, 2)}};
    AttnBlockTokenMaskParams block_token_mask_params{
        /* int64_t BTM_strides[3] = */ {
            bcast_stride(block_token_mare_admin",
    "set_admin_getters",
    "set_hf_downloader",
    "verify_session",
]


# ===== FILE: omlx/admin/accuracy_benchmark.py =====

# SPDX-License-Identifier: Apache-2.0
"""Accuracy benchmark execution logic for oMLX admin panel.

Orchestrates MMLU, HellaSwag, TruthfulQA, GSM8K, and LiveCodeBench
evaluations with real-time progress reporting via SSE events.

Supports server-side queue and persistent result accumulation.
Results survive browser close and persist until explicitly reset.
"""

import asyncio
import logging
import time
import uuid
from collections import Counter
from dataclasses import dataclass, field
from typing import Any, Literal, Optional

from pydantic import BaseModel, field_validator, model_validator

from .external_api import (
    ExternalAPIClient,
    ExternalChatAdapter,
    ExternalEndpointConfig,
)

logger = logging.getLogger(__name__)

# Module-level storage for active benchmark runs
_accuracy_runs: dict[str, "AccuracyBenchmarkRun"] = {}

# Accumulated results — persists until explicit reset
_accumulated_results: list[dict] = []

# Server-side queue
_queue: list["AccuracyBenchmarkRequest"] = []
_queue_running: bool = False
_current_run_id: Optional[str] = None
_current_model: Optional[str] = None
_engine_pool_ref: Any = None
# Chain-ownership token. A "chain" is one start_next_from_queue call plus
# the _continue_queue tail it spawns. Each chain captures the token current
# at its start; cancel_queue and start_next_from_queue bump it. A chain
# whose token is stale (e.g. it was soft-cancelled and only noticed at its
# next checkpoint, after the user already started a new chain) must not pop
# the queue or mutate _queue_running/_current_run_id — otherwise it starts
# a run concurrently with the live chain, whose Phase 1 "unload all models"
# rips the engine out from under the active run.
_chain_id: int = 0

VALID_BENCHMARKS = [
    "mmlu", "mmlu_pro", "kmmlu", "cmmlu", "jmmlu",
    "hellaswag", "truthfulqa", "arc_challenge", "winogrande",
    "gsm8k", "mathqa", "humaneval", "mbpp", "livecodebench",
    "bbq", "safetybench",
]

# Sampling profile for an accuracy run. "deterministic" (default) runs greedy
# (temperature 0) so saved scores stay reproducible; "model_settings" opts in to
# the model's configured sampling (temperature, top_p, …) for a real-world score.
SamplingProfile = Literal["deterministic", "model_settings"]


class AccuracyBenchmarkRequest(BaseModel):
    """Request model for starting an accuracy benchmark."""

    model_id: str
    benchmarks: dict[str, int]  # name -> sample_size (0 = full dataset)
    batch_size: int = 1
    enable_thinking: bool = False
    sampling_profile: SamplingProfile = "deterministic"
    # When set, the benchmark runs against a remote OpenAI-compatible
    # endpoint instead of a local engine and model_id is the remote
    # model name (not validated against the local catalog).
    external: Optional[ExternalEndpointConfig] = None

    @model_validator(mode="after")
    def _force_thinking_off_for_external(self) -> "AccuracyBenchmarkRequest":
        # enable_thinking is a local chat-template kwarg; external requests
        # never send it, so keep the stored flag honest.
        if self.external is not None:
            self.enable_thinking = False
        return self

    @field_validator("batch_size")
    @classmethod
    def validate_batch_size(cls, v: int) -> int:
        if v not in (1, 2, 4, 8, 16, 32):
            raise ValueError("batch_size must be 1, 2, 4, 8, 16, or 32")
        return v

    @field_validator("benchmarks")
    @classmethod
    def validate_benchmarks(cls, v: dict[str, int]) -> dict[str, int]:
        if not v:
            raise ValueError("At least one benchmark is required")
        for name, size in v.items():
            if name not in VALID_BENCHMARKS:
                raise ValueError(
                    f"Invalid benchmark '{name}'. Must be one of {VALID_BENCHMARKS}"
                )
            if size < 0:
                raise ValueError(f"Sample size for '{name}' must be >= 0")
        return v


@data            .foregroundStyle(theme.textSecondary)
                        Spacer(minLength: 0)
                    }
                    BenchmarkGrid(
                        selected: $selectedBenchmarks,
                        sampleSizes: $sampleSizes
                    )
                }
            }

            Row(isLast: true) {
                HStack {
                    Spacer()
                    Button {
                        onSubmit()
                    } label: {
                        if isAdding {
                            ProgressView()
                                .controlSize(.small)
                                .padding(.trailing, 2)
                            Text(String(localized: "bench.accuracy.button.adding",
                                        defaultValue: "Adding…",
                                        comment: "Accuracy Bench add-to-queue button label while the request is in flight"))
                        } else {
                            Label(String(localized: "bench.accuracy.button.add",
                                         defaultValue: "Add to Queue & Run",
                                         comment: "Accuracy Bench primary button that adds the configured run to the queue"),
                                  systemImage: "play.fill")
                                .labelStyle(.titleAndIcon)
                        }
                    }
                    .buttonStyle(.omlx(.primary))
                    .disabled(!canSubmit || isAdding)
                }
            }
        }
    }

    private var modelOptions: [PopupOption<String>] {
        var opts = [PopupOption(value: "", label: String(localized: "bench.accuracy.model.placeholder",
                                                         defaultValue: "Select a model…",
                                                         comment: "Placeholder option in the Accuracy Bench model picker"))]
        let sorted = models.sorted { (a, b) -> Bool in
            if a.loaded != b.loaded { return a.loaded && !b.loaded }
            return a.id.localizedCaseInsensitiveCompare(b.id) == .orderedAscending
        }
        opts += sorted.map { m in
            let badge = m.loaded
                ? String(localized: "bench.accuracy.model.loaded_badge",
                         defaultValue: " • loaded",
                         comment: "Suffix appended to a loaded model's name in the Accuracy Bench picker")
                : ""
            return PopupOption(value: m.id, label: "\(m.id)\(badge)")
        }
        return opts
    }

    private var subtitleText: String? {
        if models.isEmpty { return String(localized: "bench.accuracy.subtitle.loading_models",
                                          defaultValue: "Loading models…",
                                          comment: "Accuracy Bench section subtitle while models are loading") }
        let count = selectedBenchmarks.count
        return String(localized: "bench.accuracy.subtitle.selected_count",
                      defaultValue: "Benchmarks selected: \(count)",
                      comment: "Accuracy Bench section subtitle showing how many benchmarks the user has picked; placeholder is the count")
    }

    private var benchmarksSubtitle: String {
        let count = selectedBenchmarks.count
        if count == 0 { return String(localized: "bench.accuracy.benchmarks.subtitle.empty",
                                      defaultValue: "Tap to select. 0 = full dataset.",
                                      comment: "Subtitle next to the Benchmarks grid when nothing is selected") }
        return String(localized: "bench.accuracy.benchmarks.subtitle.count",
                      defaultValue: "\(count) selected",
                      comment: "Subtitle next to the Benchmarks grid showing the selected count")
    }
}

// MARK: - Benchmark grid

private struct BenchmarkGrid: View {
    @Binding var selected: Set<String>
    @Binding var sampleSizes: [String: Int]

    @State private var calculatedHeight: CGFloat = 334    continue;
                    }
                    if (k === 'index_cache_freq') {
                        if (ms.enableIndexCache) out.index_cache_freq = ms.index_cache_freq || 4;
                        continue;
                    }
                    if (k === 'max_tool_result_tokens') {
                        if (ms.enableToolResultLimit && ms.max_tool_result_tokens) {
                            out.max_tool_result_tokens = Number(ms.max_tool_result_tokens);
                        }
                        continue;
                    }
                    if (k === 'guided_grammar_enabled') {
                        out.guided_grammar_enabled = !!ms.guided_grammar_enabled;
                        continue;
                    }
                    if (k === 'guided_grammar') {
                        const g = ms.guided_grammar_enabled ? (ms.guided_grammar || '').trim() : '';
                        if (g) out.guided_grammar = g;
                        continue;
                    }
                    // Standard field: omit unset values entirely — the server
                    // treats absent universal keys as "reset to default" when
                    // the profile is applied (snapshot semantics).
                    let v = ms[k];
                    if (v === undefined || v === null || v === '') continue;
                    if (typeof v === 'string' && !isNaN(Number(v))) v = Number(v);
                    out[k] = v;
                }

                // Build chat_template_kwargs and forced_ct_kwargs from ctKwargEntries
                const ctk = {};
                const forced = [];
                for (const e of (ms.ctKwargEntries || [])) {
                    if (e.type === 'enable_thinking') {
                        if (isDiffusion) continue;
                        ctk.enable_thinking = e.value === 'true';
                        if (e.force) forced.push('enable_thinking');
                    } else if (e.type === 'reasoning_effort') {
                        if (isDiffusion) continue;
                        ctk.reasoning_effort = e.value;
                        if (e.force) forced.push('reasoning_effort');
                    } else if (e.type === 'custom' && e.key && e.key.trim()) {
                        if (isDiffusion && this.isDiffusionUnsupportedCtKwarg(e.key.trim())) {
                            continue;
                        }
                        let v = e.value;
                        if (v === 'true') v = true;
                        else if (v === 'false') v = false;
                        else if (!isNaN(Number(v)) && String(v).trim() !== '') v = Number(v);
                        ctk[e.key.trim()] = v;
                        if (e.force) forced.push(e.key.trim());
                    }
                }
                if (Object.keys(ctk).length > 0) out.chat_template_kwargs = ctk;
                if (forced.length > 0) out.forced_ct_kwargs = forced;

                return out;
            },
            formValuesForTemplate() {
                const full = this.formValuesForProfile();
                const out = {};
                for (const k of this.profileFields.universal) {
                    if (k in full) out[k] = full[k];
                }
                return out;
            },
            computeDrift() {
                if (!this.activeProfileName) { this.profilesDrift = false; return; }
                const active = this.profiles.find(p => p.name === this.activeProfileName);
                if (!active) { this.profilesDrift = false; return; }
                const form = this.formValuesForProfile();
                for (const [k, v] of Object.entries(active.settings || {})) {
                    if (JSON.stringify(form[k]) !== JSON.stringify(v)) {
                        this.profilesDrift = true;
                        return;
                    }
                }
                this.profilesDrift = false;
            },
            matchedPreset(settings) {
                // Return the preset whose universal-field settings mask, 0),
            bcast_stride(block_token_mask, 1),
            bcast_stride(block_token_mask, 2)}};

    compute_encoder.set_input_array(q, 0);
    compute_encoder.set_input_array(k, 1);
    compute_encoder.set_input_array(v, 2);
    compute_encoder.set_output_array(o, 3);
    compute_encoder.set_bytes(params, 4);
    compute_encoder.set_bytes(block_mask_params, 8);
    compute_encoder.set_input_array(block_mask, 9);
    compute_encoder.set_bytes(block_token_mask_params, 10);
    compute_encoder.set_input_array(block_token_mask, 11);

    MTL::Size grid_dims = MTL::Size(NQ, H, B);
    MTL::Size group_dims = MTL::Size(32, wm, wn);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(OMLXGlmDsaExactBlockAttention)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs =
        static_cast<const GlmDsaExactBlockAttentionPrimitive&>(other);
    return scale_ == rhs.scale_ && causal_ == rhs.causal_;
  }
  auto state() const {
    return std::make_tuple(nullptr, scale_, causal_);
  }

 private:
  float scale_;
  bool causal_;
};

} // namespace

array glm_dsa_exact_block_attention(
    const array& q,
    const array& k,
    const array& v,
    const array& block_mask,
    const array& block_token_mask,
    float scale,
    bool causal,
    StreamOrDevice s) {
  for (const auto& tensor : {q, k, v}) {
    if (tensor.ndim() != 4) {
      std::ostringstream msg;
      msg << "[omlx_glm_kernels.glm_dsa_exact_block_attention] input with "
          << "shape " << tensor.shape() << " expected rank 4.";
      throw std::invalid_argument(msg.str());
    }
  }
  auto stream = to_stream(s);
  auto final_type = result_type(std::vector<array>{q, k, v});
  if (final_type != float16 && final_type != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_exact_block_attention] expected fp16 "
        << "or bf16 inputs, got " << final_type << ".";
    throw std::invalid_argument(msg.str());
  }

  auto q_cast = astype(q, final_type, stream);
  auto k_cast = astype(k, final_type, stream);
  auto v_cast = astype(v, final_type, stream);
  if (GlmDsaExactBlockAttentionPrimitive::unsupported(
          q_cast, k_cast, v_cast, block_mask, block_token_mask, causal, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.glm_dsa_exact_block_attention] unsupported GLM exact block SDPA shape.");
  }

  Shape out_shape{q_cast.shape(0), q_cast.shape(1), q_cast.shape(2), v_cast.shape(3)};
  std::vector<array> inputs = {q_cast, k_cast, v_cast, block_mask, block_token_mask};
  return array(
      std::move(out_shape),
      final_type,
      std::make_shared<GlmDsaExactBlockAttentionPrimitive>(
          stream, scale, causal),
      std::move(inputs));
}

} // namespace omlx::glm_kernels


# ===== FILE: omlx/custom_kernels/glm_moe_dsa/csrc/fused_moe.cpp =====

#include "fused_moe.h"

#include <cstdlib>
#include <dlfcn.h>
#include <filesystem>
#include <sstream>
#include <string>

#include "mlx/backend/common/utils.h"
#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"
#include "mlx/utils.h"

namespace omlx::glm_kernels {

namespace {

using namespace mlx::core;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error("Unable to get omlx_glm_kernels binary dir.");
    }
    return std::filesystem::path(info.dli_fname).parent_path().string();
  }();
  return binary_dir;
}

bool row_contiguous(const array& arr) {
  return arr.flags().row_contiguous && arr.strides(-1) == 1;
}

struct Mxfp4BlocksVariant {
  int bm;
  int bn;
  int bk;
  int wm;
  int wn;
};

Mxfp4BlocksVariant mxfp4_blocks_variant(int variant) {
  switch (variant) {
    case 0:
      return {/* bm = */ 8, /* bn = */ 32, /* bk = */ 32, /* wm = */ 1, /* wn = */ 2};
    case 1:
      return {/* bm = */ 16, /* bn = */ 32, /* bk = */ 32, /* wm = */ 1, /* wn = */ 2};
    case 2:
      retclass
class AccuracyBenchmarkRun:
    """Tracks the state of a running accuracy benchmark.

    SSE delivery model mirrors `BenchmarkRun`: append-only `events`
    log + `cond` for live notification + `terminal` flag set on the
    final event. See benchmark.py for the rationale.
    """

    bench_id: str
    request: AccuracyBenchmarkRequest
    status: str = "running"  # running, completed, cancelled, error
    events: list[dict] = field(default_factory=list)
    cond: asyncio.Condition = field(default_factory=asyncio.Condition)
    terminal: bool = False
    task: Optional[asyncio.Task] = None
    results: list[dict] = field(default_factory=list)
    error_message: str = ""
    last_progress: Optional[dict] = None  # last progress event for reconnect
    # Finer-grained lifecycle than `status` — surfaces the difference between
    # "still scoring questions" and "cleaning up after the last result was
    # emitted". The serialization gate (_queue_running) stays True across
    # both, but a UI rendering the running row wants to hide it once
    # phase=="unloading" so the user isn't told "still running" when the
    # result card has already appeared on screen. Transitions:
    #   pending → loading → evaluating → unloading → completed
    # (cancelled / error replace the terminal phase on those branches.)
    phase: str = "pending"


# Accuracy stream closes on `done` (run finished) or `error`. Unlike the
# throughput bench there's no separate upload phase to ride out.
_ACCURACY_TERMINAL_TYPES = frozenset({"done", "error"})


# --- Run management ---


def get_run(bench_id: str) -> Optional[AccuracyBenchmarkRun]:
    """Get an accuracy benchmark run by ID."""
    return _accuracy_runs.get(bench_id)


def create_run(request: AccuracyBenchmarkRequest) -> AccuracyBenchmarkRun:
    """Create a new accuracy benchmark run."""
    bench_id = str(uuid.uuid4())[:8]
    run = AccuracyBenchmarkRun(bench_id=bench_id, request=request)
    _accuracy_runs[bench_id] = run
    return run


def cleanup_old_runs() -> None:
    """Remove completed/errored runs to prevent memory leaks."""
    to_remove = []
    for bid, run in _accuracy_runs.items():
        if run.status in ("completed", "cancelled", "error"):
            to_remove.append(bid)
    for bid in to_remove:
        del _accuracy_runs[bid]


# --- Accumulated results ---


def get_accumulated_results() -> list[dict]:
    """Get all accumulated benchmark results."""
    return _accumulated_results


def reset_accumulated_results() -> None:
    """Clear all accumulated results."""
    _accumulated_results.clear()


# --- Queue management ---


def add_to_queue(request: AccuracyBenchmarkRequest) -> None:
    """Add a benchmark request to the queue."""
    _queue.append(request)


def get_queue_status() -> dict:
    """Get current queue status."""
    last_progress = None
    phase = None
    if _current_run_id:
        run = get_run(_current_run_id)
        if run:
            last_progress = run.last_progress
            phase = run.phase
    return {
        "running": _queue_running,
        "current_model": _current_model,
        "current_bench_id": _current_run_id,
        "last_progress": last_progress,
        # Finer-grained than `running`: distinguishes "still scoring" from
        # "cleaning up after the last result emitted". Polling UIs hide
        # the running row once phase becomes "unloading" / "completed" so
        # the result card alone tells the story.
        "phase": phase,
        "queue": [
            {
                "model_id": r.model_id,
                "benchmarks": list(r.benchmarks.keys()),
                "external": r.external is not None,
            }
            for r in _queue
        ],
    }


def remove_from_queue(idx: int) -> bool:
    """Remove an item from the queue by index."""
    if 0 <= idx < len(_queue):
        _queue.pop(idx)
        return True
    return False


def start_next_from_queue(engine_pool: Any) -> Optional[str]:
    """Pop next item from queue, create run, start background task.

    Returns bench_id if a run w

    private struct GridHeightKey: PreferenceKey {
        static let defaultValue: CGFloat = 334
        static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
            value = max(value, nextValue())
        }
    }

    var body: some View {
        GeometryReader { geo in
            let cols = geo.size.width > 600 ? 3 : 2
            let layout = Array(
                repeating: GridItem(.flexible(), spacing: 8),
                count: cols
            )

            LazyVGrid(columns: layout, alignment: .leading, spacing: 8) {
                ForEach(benchmarkCatalog) { entry in
                    BenchmarkCard(
                        entry: entry,
                        isSelected: selected.contains(entry.key),
                        sampleSize: binding(for: entry.key),
                        onToggle: { toggle(entry.key) }
                    )
                    .frame(maxHeight: .infinity, alignment: .top)
                }
            }
            .background {
                GeometryReader { contentGeo in
                    Color.clear
                        .preference(key: GridHeightKey.self, value: contentGeo.size.height)
                }
            }
        }
        .frame(height: calculatedHeight)
        .onPreferenceChange(GridHeightKey.self) { height in
            withAnimation {
                self.calculatedHeight = height
            }
        }
    }

    private func toggle(_ key: String) {
        withAnimation {
            if selected.contains(key) {
                selected.remove(key)
            } else {
                selected.insert(key)
                if sampleSizes[key] == nil { sampleSizes[key] = 100 }
            }
        }
    }

    private func binding(for key: String) -> Binding<Int> {
        Binding(
            get: { sampleSizes[key] ?? 100 },
            set: { sampleSizes[key] = $0 }
        )
    }
}

private struct BenchmarkCard: View {
    let entry: BenchmarkCatalogEntry
    let isSelected: Bool
    @Binding var sampleSize: Int
    let onToggle: () -> Void

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        VStack(alignment: .leading, spacing: 6) {
            Toggle(isOn: Binding(
                get: { isSelected },
                set: { _ in onToggle() }
            )) {
                HStack {
                    VStack(alignment: .leading, spacing: 1) {
                        Text(entry.displayName)
                            .font(.omlxText(12.5, weight: .medium))
                            .foregroundStyle(theme.text)
                        Text(entry.category)
                            .font(.omlxText(10.5))
                            .foregroundStyle(theme.textTertiary)
                    }
                    Spacer()
                }
            }

            if isSelected {
                HStack(spacing: 6) {
                    Text(String(localized: "bench.accuracy.card.samples_label",
                                defaultValue: "Samples:",
                                comment: "Inline label next to the per-benchmark sample-size dropdown"))
                        .font(.omlxText(10.5))
                        .foregroundStyle(theme.textTertiary)
                    Popup(
                        selection: $sampleSize,
                        width: 90,
                        options: sampleSizeOptions
                    )
                }
            }
        }
        .padding(10)
        .background(
            RoundedRectangle(cornerRadius: 7, style: .continuous)
                .fill(isSelected ? theme.controlBg : Color.clear)
        )
        .overlay(
            RoundedRectangle(cornerRadius: 7, style: .continuous)
                .strokeBorder(
                    isSelected ? theme.inputBorder : theme.groupBorder,
                    lineWidth: 0.5
                )
        )
    }
}

// MARK: - Queue

private struct QueueSection: View {
    let status: AccuracyQueueStatus?
    let onCancel: () -> Void
    let onRemove: (Int) -> Void

    @Environment(\.tch the current model
                // settings exactly, otherwise null. Used by the models list to show "which
                // preset was applied" as a pill without any server-side tracking.
                if (!settings || !this.presets || this.presets.length === 0) return null;
                const universal = this.profileFields.universal || [];
                if (universal.length === 0) return null;
                const canonical = v => {
                    if (v === undefined || v === null || v === false) return null;
                    if (typeof v === 'object') {
                        return JSON.stringify(v, Object.keys(v).sort());
                    }
                    return v;
                };
                for (const p of this.presets) {
                    const ps = p.settings || {};
                    let ok = true;
                    for (const k of universal) {
                        if (canonical(ps[k]) !== canonical(settings[k])) {
                            ok = false;
                            break;
                        }
                    }
                    if (ok) return p;
                }
                return null;
            },
            profileTooltip(profile) {
                const lines = [];
                if (profile?.expose_as_model && profile.model_id) {
                    lines.push(profile.model_id);
                }
                const description = (profile?.description || '').trim();
                if (description) lines.push(description);
                return lines.join('\n');
            },
            async loadProfilesForModel(modelId) {
                this.profiles = [];
                try {
                    const r = await fetch(`/admin/api/models/${encodeURIComponent(modelId)}/profiles`);
                    if (r.ok) {
                        const data = await r.json();
                        this.profiles = data.profiles || [];
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (e) {
                    console.error('Failed to load profiles:', e);
                }
            },
            async loadTemplates() {
                try {
                    const r = await fetch('/admin/api/profile-templates');
                    if (r.ok) {
                        const data = await r.json();
                        this.templates = data.templates || [];
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (e) {
                    console.error('Failed to load templates:', e);
                }
            },
            async loadProfileFields() {
                try {
                    const r = await fetch('/admin/api/profile-fields');
                    if (r.ok) {
                        const data = await r.json();
                        this.profileFields = {
                            universal: data.universal || [],
                            model_specific: data.model_specific || [],
                        };
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (e) {
                    console.error('Failed to load profile field definitions:', e);
                }
            },

            async loadPresets() {
                // Use localStorage cache if present, otherwise fall back to the bundled file.
                const cached = localStorage.getItem('omlx_preset_cache');
                if (cached) {
                    try {
                        const parsed = JSON.parse(cached);
                        this.presets = parsed.presets || [];
                        return;
                    } catch (e) { /* corrupted, fall through */ }
                }
                try {
                    const r = await fetch('/admin/static/omlx_preset.json');
                    if (r.ok) {
     urn {/* bm = */ 32, /* bn = */ 32, /* bk = */ 32, /* wm = */ 1, /* wn = */ 2};
    case 3:
      return {/* bm = */ 16, /* bn = */ 64, /* bk = */ 32, /* wm = */ 1, /* wn = */ 2};
    case 4:
      return {/* bm = */ 32, /* bn = */ 64, /* bk = */ 32, /* wm = */ 1, /* wn = */ 2};
    default: {
      std::ostringstream msg;
      msg << "Unsupported DeepSeek MXFP4 block-list variant " << variant << ".";
      throw std::invalid_argument(msg.str());
    }
  }
}

int affine_pack_factor(int bits) {
  switch (bits) {
    case 2:
      return 4;
    case 3:
      return 8;
    case 4:
      return 2;
    case 8:
      return 1;
    default:
      return 0;
  }
}

int affine_bytes_per_pack(int bits) {
  switch (bits) {
    case 2:
      return 1;
    case 3:
      return 3;
    case 4:
      return 1;
    case 8:
      return 1;
    default:
      return 0;
  }
}

bool supported_deepseek_affine(int group_size, int bits) {
  return group_size == 64 && (bits == 2 || bits == 3);
}

int affine_packed_row_bytes(int K, int bits) {
  const int pack_factor = affine_pack_factor(bits);
  const int bytes_per_pack = affine_bytes_per_pack(bits);
  if (pack_factor == 0 || bytes_per_pack == 0 || K % pack_factor != 0) {
    return -1;
  }
  return K * bytes_per_pack / pack_factor;
}

std::string glm_type_name(Dtype dtype) {
  if (dtype == float16) {
    return "float16_t";
  }
  if (dtype == bfloat16) {
    return "bfloat16_t";
  }
  std::ostringstream msg;
  msg << "Unsupported GLM fused kernel dtype: " << dtype << ".";
  throw std::invalid_argument(msg.str());
}

class GlmDsaQ8VupFlatPrimitive : public Primitive {
 public:
  explicit GlmDsaQ8VupFlatPrimitive(Stream stream) : Primitive(stream) {}

  static bool unsupported(
      const array& x,
      const array& weight,
      const array& scales,
      const array& biases,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (x.dtype() != float16 && x.dtype() != bfloat16) {
      return true;
    }
    if (weight.dtype() != uint32 || scales.dtype() != x.dtype() ||
        biases.dtype() != x.dtype()) {
      return true;
    }
    if (x.ndim() != 4 || weight.ndim() != 3 || scales.ndim() != 3 ||
        biases.ndim() != 3) {
      return true;
    }
    if (!row_contiguous(x) || !row_contiguous(weight) ||
        !row_contiguous(scales) || !row_contiguous(biases)) {
      return true;
    }

    constexpr int bits = 8;
    constexpr int group_size = 64;
    constexpr int pack_factor = 32 / bits;
    const int H = x.shape(1);
    const int K = x.shape(3);
    const int N = weight.shape(1);
    if (H != 64 || K != 512 || N != 256) {
      return true;
    }
    if (weight.shape(0) != H || scales.shape(0) != H ||
        biases.shape(0) != H || scales.shape(1) != N ||
        biases.shape(1) != N || weight.shape(2) * pack_factor != K ||
        scales.shape(2) != K / group_size ||
        biases.shape(2) != K / group_size) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("GlmDsaQ8VupFlatPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x = inputs[0];
    const auto& weight = inputs[1];
    const auto& scales = inputs[2];
    const auto& biases = inputs[3];

    out.set_data(allocator::malloc(out.nbytes()));

    constexpr int group_size = 64;
    constexpr int bits = 8;
    constexpr int bm = 32;
    constexpr int bn = 32;

    const int B = x.shape(0);
    const int H = x.shape(1);
    const int M = x.shape(2);
    const int K = x.shape(3);
    const int N = weight.shape(1);

    std::string kname;
    concatenate(
        kname,
        "affine_qmm_t_head_flat_",
        glm_type_name(x.dtype()),
        "_gs_",
        group_size,
        "_b_",
        bits,
        "_alN_true");

    auto lib = d.get_library("omlx_glm_kernelas started, None if already running or queue empty.
    This is synchronous so the caller gets the bench_id immediately.
    """
    global _queue_running, _current_run_id, _current_model, _engine_pool_ref
    global _chain_id

    _engine_pool_ref = engine_pool

    if _queue_running:
        return None

    if not _queue:
        return None

    request = _queue.pop(0)
    _queue_running = True
    _current_model = request.model_id
    # This chain takes ownership of the queue; any earlier chain still
    # draining a soft-cancelled run bails at its next _continue_queue call.
    _chain_id += 1
    my_chain = _chain_id

    cleanup_old_runs()
    run = create_run(request)
    _current_run_id = run.bench_id

    logger.info(
        f"Queue: starting {request.model_id} "
        f"benchmarks={list(request.benchmarks.keys())}"
    )

    async def _run_and_continue():
        try:
            await run_accuracy_benchmark(run, engine_pool)
        except Exception as e:
            logger.error(f"Queue: error running {request.model_id}: {e}")
        # Auto-continue with next in queue
        await _continue_queue(engine_pool, my_chain)

    run.task = asyncio.create_task(_run_and_continue())
    return run.bench_id


async def _continue_queue(engine_pool: Any, chain_id: int) -> None:
    """Continue processing the queue after a run completes.

    `chain_id` is the ownership token captured when this chain started.
    A stale chain (orphaned by cancel_queue, with a new chain started by
    the user since) returns without popping the queue or touching the
    gate, so it cannot start a run concurrently with the live chain.
    """
    global _queue_running, _current_run_id, _current_model

    if chain_id != _chain_id:
        return

    if not _queue:
        _queue_running = False
        _current_run_id = None
        _current_model = None
        return

    request = _queue.pop(0)
    _current_model = request.model_id

    cleanup_old_runs()
    run = create_run(request)
    _current_run_id = run.bench_id
    # Queue-continued runs execute inside this chain's own task; record it
    # so cancel_queue can hard-cancel them instead of waiting for the next
    # on_progress checkpoint (up to a full generation batch away).
    run.task = asyncio.current_task()

    logger.info(
        f"Queue: continuing with {request.model_id} "
        f"benchmarks={list(request.benchmarks.keys())}"
    )

    try:
        await run_accuracy_benchmark(run, engine_pool)
    except Exception as e:
        logger.error(f"Queue: error running {request.model_id}: {e}")

    await _continue_queue(engine_pool, chain_id)


async def cancel_queue() -> None:
    """Cancel the current run and clear the queue."""
    global _queue_running, _current_run_id, _current_model, _chain_id

    _queue.clear()
    # Orphan the live chain before releasing the gate: if the cancelled run
    # only notices at its next checkpoint, its trailing _continue_queue must
    # not race whatever chain the user starts after this cancel.
    _chain_id += 1

    if _current_run_id:
        run = get_run(_current_run_id)
        if run and run.status == "running":
            run.status = "cancelled"
            if run.task and not run.task.done():
                run.task.cancel()

    _queue_running = False
    _current_run_id = None
    _current_model = None


# --- SSE ---


async def _send_event(run: AccuracyBenchmarkRun, event: dict) -> None:
    """Append an event to the run's log and wake subscribers.

    Updates `last_progress` (used by the REST `queue/status` endpoint
    for reconnect hints) and sets `run.terminal` on the final event.
    """
    if event.get("type") == "progress":
        run.last_progress = event
    async with run.cond:
        run.events.append(event)
        if event.get("type") in _ACCURACY_TERMINAL_TYPES:
            run.terminal = True
        run.cond.notify_all()


# --- Benchmark execution ---


async def run_accuracy_benchmark(
    run: AccuracyBenchmarkRun, engine_pool: Any
) -> None:
    """Execute accuracy benchmark run.

   omlxTheme) private var theme

    var body: some View {
        // Use `isActivelyEvaluating` instead of bare `running`: the
        // server's `running` stays True while the bench task is alive,
        // including the post-result model-unload window. During that
        // window the result card is already on screen, so showing a
        // "Running" row with the final progress message reads as the
        // task being stuck. See AccuracyQueueStatus.isActivelyEvaluating.
        let activelyRunning = status?.isActivelyEvaluating == true
        let queue = status?.queue ?? []
        let showSection = activelyRunning || !queue.isEmpty

        if showSection {
            SectionHeader(String(localized: "bench.accuracy.section.queue",
                                 defaultValue: "Queue",
                                 comment: "Section header for the Accuracy Bench queue/in-progress block"),
                          subtitle: subtitle(running: activelyRunning, queue: queue))

            ListGroup {
                if activelyRunning {
                    let isLast = queue.isEmpty
                    FreeRow(isLast: isLast) {
                        RunningRow(
                            modelId: status?.currentModel ?? "",
                            progress: status?.lastProgress,
                            onCancel: onCancel
                        )
                    }
                }

                ForEach(Array(queue.enumerated()), id: \.offset) { idx, item in
                    FreeRow(isLast: idx == queue.count - 1) {
                        QueuedRow(
                            index: idx,
                            item: item,
                            onRemove: { onRemove(idx) }
                        )
                    }
                }
            }
        }
    }

    private func subtitle(running: Bool, queue: [AccuracyQueueItem]) -> String {
        let queuedCount = queue.count
        let queuedPart = String(localized: "bench.accuracy.queue.subtitle.queued",
                                defaultValue: "\(queuedCount) queued",
                                comment: "Accuracy Bench queue subtitle fragment showing queued count")
        if running {
            return String(localized: "bench.accuracy.queue.subtitle.with_running",
                          defaultValue: "\(queuedPart) · 1 running",
                          comment: "Accuracy Bench queue subtitle when one bench is running; placeholder is the queued-count fragment")
        }
        if queuedCount == 0 {
            return String(localized: "bench.accuracy.queue.subtitle.empty",
                          defaultValue: "no active runs",
                          comment: "Accuracy Bench queue subtitle when nothing is running or queued")
        }
        return queuedPart
    }
}

private struct RunningRow: View {
    let modelId: String
    let progress: AccuracyProgressDTO?
    let onCancel: () -> Void

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack(spacing: 8) {
                ProgressView()
                    .controlSize(.small)
                Text(modelId.isEmpty
                     ? String(localized: "bench.accuracy.queue.running.placeholder",
                              defaultValue: "Running…",
                              comment: "Accuracy Bench running-row title when the server hasn't reported the model id yet")
                     : modelId)
                    .font(.omlxMono(12))
                    .foregroundStyle(theme.text)
                    .lineLimit(1)
                    .truncationMode(.middle)
                StatusPill(status: .custom(
                    color: theme.blueDot,
                    label: String(localized: "bench.accuracy.status.running",
                                  defaultValue: "Running",
                                  comment: "Status pill label on the Accuracy Bench running row"),
                    fillBg: true
                ))
                                  const data = await r.json();
                        this.presets = data.presets || [];
                    }
                } catch (e) {
                    console.error('Failed to load bundled presets:', e);
                }
            },

            async refreshPresets() {
                if (this.refreshingPresets) return;
                this.refreshingPresets = true;
                try {
                    const r = await fetch('/admin/api/presets/refresh', { method: 'POST' });
                    if (r.ok) {
                        const data = await r.json();
                        this.presets = data.presets || [];
                        localStorage.setItem('omlx_preset_cache', JSON.stringify(data));
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (e) {
                    console.error('Preset refresh failed:', e);
                } finally {
                    this.refreshingPresets = false;
                }
            },

            // Floating tooltip shared by preset/profile pills (position:fixed escapes
            // the scroll container's overflow clipping, unlike absolute+group-hover).
            tip: { visible: false, text: '', x: 0, y: 0 },

            showTip(el, text) {
                if (!text) return;
                const rect = el.getBoundingClientRect();
                this.tip = {
                    visible: true,
                    text: text,
                    x: rect.left + rect.width / 2,
                    y: rect.bottom + 6,
                };
            },
            hideTip() {
                this.tip.visible = false;
            },

            isDiffusionModel(model) {
                const modelType = String(model?.config_model_type || '')
                    .toLowerCase()
                    .replace(/-/g, '_');
                return DIFFUSION_CONFIG_MODEL_TYPES.has(modelType);
            },

            isDiffusionUnsupportedProfileField(field) {
                return DIFFUSION_UNSUPPORTED_PROFILE_FIELDS.has(field);
            },

            isDiffusionUnsupportedCtKwarg(key) {
                return DIFFUSION_UNSUPPORTED_CT_KWARGS.has(key);
            },

            draftModelSearchText(model) {
                return [
                    model?.id,
                    model?.name,
                    model?.model_path,
                    model?.source_repo_id,
                    model?.config_model_type,
                ].filter(Boolean).join(' ').toLowerCase();
            },

            isDraftModelBaseCandidate(model) {
                if (!model || model.virtual) return false;
                if (model.id === this.selectedModel?.id) return false;
                return model.model_type === 'llm' || model.model_type === 'vlm' || !model.model_type;
            },

            isDflashDraftModel(model) {
                return /(^|[-_/\s])dflash($|[-_/\s])/i.test(this.draftModelSearchText(model));
            },

            isVlmMtpDraftModel(model) {
                const configType = String(model?.config_model_type || '').toLowerCase();
                if (configType) {
                    return VLM_MTP_DRAFTER_CONFIG_MODEL_TYPES.has(configType);
                }
                return /assistant|(^|[-_/\s])mtp($|[-_/\s])/i.test(this.draftModelSearchText(model));
            },

            isSpecPrefillDraftModel(model) {
                return !this.isDflashDraftModel(model)
                    && !this.isVlmMtpDraftModel(model);
            },

            draftModelCandidates(filterFn, { fallbackToBase = true } = {}) {
                const base = (this.models || []).filter((model) => (
                    this.isDraftModelBaseCandidate(model)
                ));
                const filtered = base.filter(filterFn);
                return (filtered.length > 0 || !fallbackToBase) ? filtered : base;
            },

            specPrefillDraftModelCandidates() {
                return this.draftModelCandidas", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.set_compute_pipeline_state(kernel);
    compute_encoder.set_input_array(weight, 0);
    compute_encoder.set_input_array(scales, 1);
    compute_encoder.set_input_array(biases, 2);
    compute_encoder.set_input_array(x, 3);
    compute_encoder.set_output_array(out, 4);
    compute_encoder.set_bytes(K, 5);
    compute_encoder.set_bytes(N, 6);
    compute_encoder.set_bytes(M, 7);
    compute_encoder.set_bytes(H, 8);

    MTL::Size grid_dims((N + bn - 1) / bn, (M + bm - 1) / bm, B * H);
    MTL::Size group_dims(32, 2, 2);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(GlmDsaQ8VupFlatPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& /* other */) const override {
    return true;
  }
  auto state() const {
    return std::make_tuple(nullptr);
  }

};

class GlmMoeWeightedSumPrimitive : public Primitive {
 public:
  explicit GlmMoeWeightedSumPrimitive(Stream stream) : Primitive(stream) {}

  static bool unsupported(
      const array& x_sorted,
      const array& inv_order,
      const array& scores,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (x_sorted.dtype() != float16 && x_sorted.dtype() != bfloat16) {
      return true;
    }
    if (scores.dtype() != float32 || inv_order.dtype() != uint32) {
      return true;
    }
    if (x_sorted.ndim() != 3 || x_sorted.shape(-2) != 1 ||
        scores.ndim() < 2 || inv_order.ndim() != 1) {
      return true;
    }
    if (!row_contiguous(x_sorted) || !row_contiguous(inv_order) ||
        !row_contiguous(scores)) {
      return true;
    }
    const int topk = scores.shape(-1);
    if ((topk != 6 && topk != 8) || x_sorted.shape(0) != scores.size() ||
        inv_order.size() != scores.size()) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("GlmMoeWeightedSumPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x_sorted = inputs[0];
    const auto& inv_order = inputs[1];
    const auto& scores = inputs[2];

    out.set_data(allocator::malloc(out.nbytes()));

    const int topk = scores.shape(-1);
    const int tokens = scores.size() / topk;
    const int D = x_sorted.shape(-1);

    const bool use_tiled = true;
    const int tiled_threads = 256;
    const int vec = (D % 4 == 0) ? 4 : 1;

    std::string kname;
    if (use_tiled) {
      concatenate(
          kname,
          "moe_weighted_sum_tiled_",
          glm_type_name(x_sorted.dtype()),
          "_score_float_topk_",
          topk,
          "_t_",
          tiled_threads);
    } else {
      concatenate(
          kname,
          vec == 1 ? "moe_weighted_sum_" : "moe_weighted_sum_vec",
          vec == 1 ? "" : std::to_string(vec),
          vec == 1 ? "" : "_",
          glm_type_name(x_sorted.dtype()),
          "_score_float_topk_",
          topk);
    }

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.set_compute_pipeline_state(kernel);
    compute_encoder.set_input_array(x_sorted, 0);
    compute_encoder.set_input_array(inv_order, 1);
    compute_encoder.set_input_array(scores, 2);
    compute_encoder.set_output_array(out, 3);
    compute_encoder.set_bytes(tokens, 4);
    compute_encoder.set_bytes(D, 5);

    const int threads = use_tiled ? tiled_threads : 256;
    const int total = vec == 1 ? tokens * D : tokens * ((D + vec - 1) / vec);
    MTL::Size group_dims(threads, 1, 1);
    MTL::Size grid_dims(
        use_tiled ? tokens : (total + threads - 1) / threads, 1, 1);
    compute_encoder. Phases:
    1. Unload all models
    2. Load target model
    3. For each selected benchmark: load data, evaluate, report
    4. Unload model
    5. Send done event
    """
    from ..eval import BENCHMARKS

    request = run.request

    # Suppress TTL auto-unload during benchmark (local engines only)
    if request.external is None:
        engine_pool._suppress_ttl = True
    start_time = time.time()
    client: Optional[ExternalAPIClient] = None

    try:
        run.phase = "loading"
        if request.external is not None:
            # External endpoint: no local model lifecycle. The adapter owns
            # the sampling-profile mapping, so sampling_kwargs stays empty
            # (enable_thinking is already forced off by request validation).
            await _send_event(run, {
                "type": "progress",
                "phase": "connect",
                "model_id": request.model_id,
                "benchmark": "",
                "message": f"Connecting to {request.external.base_url}...",
                "current": 0,
                "total": len(request.benchmarks),
            })
            client = ExternalAPIClient(request.external)
            engine = ExternalChatAdapter(client, request.sampling_profile)
            # Fail fast on auth/URL/model errors so a wrong API key cannot
            # silently produce a 0% score.
            await engine.preflight()
            sampling_kwargs = {}
        else:
            # Phase 1: Unload all models
            loaded_ids = engine_pool.get_loaded_model_ids()
            if loaded_ids:
                await _send_event(run, {
                    "type": "progress",
                    "phase": "unload",
                    "model_id": request.model_id,
                    "benchmark": "",
                    "message": f"Unloading {len(loaded_ids)} model(s)...",
                    "current": 0,
                    "total": len(request.benchmarks),
                })
                for model_id in loaded_ids:
                    try:
                        await engine_pool._unload_engine(model_id)
                    except Exception as e:
                        logger.warning(f"Failed to unload {model_id}: {e}")

            # Phase 2: Load target model
            await _send_event(run, {
                "type": "progress",
                "phase": "load",
                "model_id": request.model_id,
                "benchmark": "",
                "message": f"Loading {request.model_id}...",
                "current": 0,
                "total": len(request.benchmarks),
            })

            # Force LM engine for accuracy benchmarks — text-only tasks
            # don't need VLM and the VLM adapter can produce empty responses.
            engine = await engine_pool.get_engine(request.model_id, force_lm=True)

            # Load model sampling settings. Under the default "deterministic"
            # profile sampling params are not read — the benchmark runs greedy
            # (temperature 0) so saved scores stay reproducible. Only the
            # explicit "model_settings" opt-in honors the model's configured
            # sampling. chat_template_kwargs is prompt construction, not
            # sampling, so it is forwarded in both profiles.
            sampling_kwargs = {}
            if engine_pool._settings_manager is not None:
                ms = engine_pool._settings_manager.get_settings(request.model_id)
                if ms.chat_template_kwargs:
                    sampling_kwargs["chat_template_kwargs"] = ms.chat_template_kwargs
                if request.sampling_profile == "model_settings":
                    if ms.temperature is not None:
                        sampling_kwargs["temperature"] = ms.temperature
                    if ms.top_p is not None:
                        sampling_kwargs["top_p"] = ms.top_p
                    if ms.top_k is not None:
                        sampling_kwargs["top_k"] = ms.top_k
                    if ms.min_p is not None:
                        sampling_kwargs["min_p"] = ms.min_p
  Spacer(minLength: 6)
                Button(action: onCancel) {
                    Label(String(localized: "common.cancel",
                                 defaultValue: "Cancel",
                                 comment: "Generic Cancel button label"),
                          systemImage: "stop.fill")
                        .labelStyle(.titleAndIcon)
                }
                .buttonStyle(.omlx(.destructive, size: .small))
            }
            if let line = progressLine {
                Text(line)
                    .font(.omlxText(11))
                    .foregroundStyle(theme.textSecondary)
                    .lineLimit(2)
                    .fixedSize(horizontal: false, vertical: true)
            }
        }
    }

    private var progressLine: String? {
        guard let p = progress else { return nil }
        var bits: [String] = []
        if let bench = p.benchmark, !bench.isEmpty { bits.append(bench) }
        if let msg = p.message, !msg.isEmpty { bits.append(msg) }
        if let cur = p.current, let tot = p.total, tot > 0 {
            bits.append("\(cur)/\(tot)")
        }
        if let bCur = p.benchCurrent, let bTot = p.benchTotal, bTot > 0 {
            bits.append("bench \(bCur)/\(bTot)")
        }
        return bits.isEmpty ? nil : bits.joined(separator: " · ")
    }
}

private struct QueuedRow: View {
    let index: Int
    let item: AccuracyQueueItem
    let onRemove: () -> Void

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        HStack(alignment: .center, spacing: 8) {
            Image(systemName: "list.bullet.rectangle")
                .font(.system(size: 12))
                .foregroundStyle(theme.textTertiary)
            VStack(alignment: .leading, spacing: 2) {
                Text(item.modelId)
                    .font(.omlxMono(12))
                    .foregroundStyle(theme.text)
                    .lineLimit(1)
                    .truncationMode(.middle)
                Text(item.benchmarks.map(displayName(for:)).joined(separator: ", "))
                    .font(.omlxText(11))
                    .foregroundStyle(theme.textSecondary)
                    .lineLimit(2)
                    .fixedSize(horizontal: false, vertical: true)
            }
            Spacer(minLength: 6)
            Button {
                onRemove()
            } label: {
                Image(systemName: "xmark")
                    .font(.system(size: 11))
            }
            .buttonStyle(.omlx(.plain, size: .small))
            .help(String(localized: "bench.accuracy.queue.remove.help",
                         defaultValue: "Remove from queue",
                         comment: "Tooltip on the X button next to a queued Accuracy Bench entry"))
        }
    }

    private func displayName(for key: String) -> String {
        benchmarkCatalog.first(where: { $0.key == key })?.displayName ?? key
    }
}


// MARK: - Results

private struct ResultsSection: View {
    let results: [AccuracyResultDTO]
    let onClear: () -> Void

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        if !results.isEmpty {
            SectionHeader(
                String(localized: "bench.accuracy.section.results",
                       defaultValue: "Results",
                       comment: "Section header for the Accuracy Bench results list"),
                subtitle: String(localized: "bench.accuracy.results.subtitle",
                                 defaultValue: "Results: \(results.count)",
                                 comment: "Subtitle showing the number of accumulated Accuracy Bench results")
            ) {
                Button(String(localized: "bench.accuracy.results.clear_all",
                              defaultValue: "Clear all",
                              comment: "Button in the Accuracy Bench results header that resets the result list")) { onClear() }
                    .buttonStyle(.omlx(.plain, size: .small))
                    .foregroundStyle(theme.redDot)
            }

            ListGroup {
      tes((model) => this.isSpecPrefillDraftModel(model));
            },

            dflashDraftModelCandidates() {
                return this.draftModelCandidates((model) => this.isDflashDraftModel(model));
            },

            vlmMtpDraftModelCandidates() {
                return this.draftModelCandidates(
                    (model) => this.isVlmMtpDraftModel(model),
                    { fallbackToBase: false },
                );
            },

            // Settings that materialize as per-request logits processors,
            // which the VLM MTP decode path cannot apply (#2399). Mirrors
            // vlm_mtp_processor_conflicts() in model_settings.py; neutral
            // values (repetition 1.0, presence 0.0) do not conflict.
            vlmMtpProcessorConflict() {
                const ms = this.modelSettings;
                if (!ms) return false;
                const num = (v) => (v === null || v === undefined || v === '' ? null : Number(v));
                const rep = num(ms.repetition_penalty);
                const pres = num(ms.presence_penalty);
                return (rep !== null && rep !== 1.0)
                    || (pres !== null && pres !== 0.0)
                    || !!ms.enableThinkingBudget
                    || !!ms.guided_grammar_enabled;
            },

            buildCtKwargEntries(chatTemplateKwargs, forcedCtKwargs, isDiffusion = false) {
                const ctk = chatTemplateKwargs || {};
                const forced = new Set(forcedCtKwargs || []);
                const entries = [];
                for (const [key, value] of Object.entries(ctk)) {
                    if (isDiffusion && this.isDiffusionUnsupportedCtKwarg(key)) {
                        continue;
                    }
                    if (key === 'enable_thinking') {
                        entries.push({
                            type: 'enable_thinking',
                            value: String(value),
                            force: forced.has('enable_thinking'),
                        });
                    } else if (key === 'reasoning_effort') {
                        entries.push({
                            type: 'reasoning_effort',
                            value: String(value),
                            force: forced.has('reasoning_effort'),
                        });
                    } else {
                        entries.push({
                            type: 'custom',
                            key,
                            value: String(value),
                            force: forced.has(key),
                        });
                    }
                }
                return entries;
            },

            buildModelSettingsState(model, settings) {
                const s = settings || {};
                const isDiffusion = this.isDiffusionModel(model);
                const ctKwargEntries = this.buildCtKwargEntries(
                    s.chat_template_kwargs,
                    s.forced_ct_kwargs,
                    isDiffusion,
                );
                const isOcr = OCR_CONFIG_MODEL_TYPES.has(model?.config_model_type || '');
                return {
                    model_alias: s.model_alias || '',
                    model_type_override: s.model_type_override || '',
                    max_context_window: s.max_context_window || null,
                    max_tokens: s.max_tokens || null,
                    temperature: isOcr ? 0.0 : (s.temperature ?? null),
                    top_p: s.top_p ?? null,
                    top_k: s.top_k ?? null,
                    repetition_penalty: s.repetition_penalty ?? null,
                    min_p: s.min_p ?? null,
                    presence_penalty: s.presence_penalty ?? null,
                    force_sampling: s.force_sampling || false,
                    enable_thinking: s.enable_thinking ?? null,
                    thinking_default: model?.thinking_default ?? null,
                    enableThinkingBudget: !!(s.thinking_budget_tokens),
                    thinking_budget_tokens: s.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(GlmMoeWeightedSumPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& /* other */) const override {
    return true;
  }
  auto state() const {
    return std::make_tuple(nullptr);
  }

};

class DeepseekMxfp4GatherBlocksPrimitive : public Primitive {
 public:
  explicit DeepseekMxfp4GatherBlocksPrimitive(Stream stream, int variant)
      : Primitive(stream), variant_(variant) {
    (void)mxfp4_blocks_variant(variant_);
  }

  static bool unsupported(
      const array& x,
      const array& weight,
      const array& scales,
      const array& block_meta,
      const array& block_count,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (x.dtype() != float16 && x.dtype() != bfloat16) {
      return true;
    }
    if (weight.dtype() != uint32 || scales.dtype() != uint8 ||
        block_meta.dtype() != int32 || block_count.dtype() != int32) {
      return true;
    }
    if (x.ndim() != 3 || x.shape(1) != 1 || weight.ndim() != 3 ||
        scales.ndim() != 3 || block_meta.ndim() != 2 ||
        block_meta.shape(1) != 3 || block_count.size() != 1) {
      return true;
    }
    if (!row_contiguous(x) || !row_contiguous(weight) ||
        !row_contiguous(scales) || !row_contiguous(block_meta) ||
        !row_contiguous(block_count)) {
      return true;
    }

    constexpr int bits = 4;
    constexpr int group_size = 32;
    constexpr int values_per_uint32 = 32 / bits;
    const int K = x.shape(2);
    const int E = weight.shape(0);
    const int N = weight.shape(1);
    if (x.shape(0) <= 0 || K <= 0 || N <= 0 || E <= 0 ||
        block_meta.shape(0) <= 0) {
      return true;
    }
    if (weight.shape(2) * values_per_uint32 != K || scales.shape(0) != E ||
        scales.shape(1) != N || scales.shape(2) != K / group_size) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error(
        "DeepseekMxfp4GatherBlocksPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x = inputs[0];
    const auto& weight = inputs[1];
    const auto& scales = inputs[2];
    const auto& block_meta = inputs[3];
    const auto& block_count = inputs[4];

    out.set_data(allocator::malloc(out.nbytes()));

    const auto cfg = mxfp4_blocks_variant(variant_);
    const int max_blocks = block_meta.shape(0);
    const int M = x.shape(0);
    const int K = x.shape(2);
    const int N = weight.shape(1);

    std::string kname;
    concatenate(
        kname,
        "deepseek_mxfp4_gather_blocks_rhs_",
        glm_type_name(x.dtype()),
        "_bm_",
        cfg.bm,
        "_bn_",
        cfg.bn,
        "_bk_",
        cfg.bk,
        "_wm_",
        cfg.wm,
        "_wn_",
        cfg.wn);

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.set_compute_pipeline_state(kernel);
    compute_encoder.set_input_array(x, 0);
    compute_encoder.set_input_array(weight, 1);
    compute_encoder.set_input_array(scales, 2);
    compute_encoder.set_input_array(block_meta, 3);
    compute_encoder.set_input_array(block_count, 4);
    compute_encoder.set_output_array(out, 5);
    compute_encoder.set_bytes(max_blocks, 6);
    compute_encoder.set_bytes(M, 7);
    compute_encoder.set_bytes(N, 8);
    compute_encoder.set_bytes(K, 9);

    MTL::Size grid_dims((N + cfg.bn - 1) / cfg.bn, max_blocks, 1);
    MTL::Size group_dims(cfg.wm * cfg.wn * 32, 1, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(DeepseekMxfp4GatherBlocksPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& r                   if ms.repetition_penalty is not None:
                        sampling_kwargs["repetition_penalty"] = ms.repetition_penalty
                    if ms.presence_penalty is not None:
                        sampling_kwargs["presence_penalty"] = ms.presence_penalty

        # Phase 3: Run each benchmark
        run.phase = "evaluating"
        completed = 0
        for bench_name, sample_size in request.benchmarks.items():
            if run.status == "cancelled":
                break

            bench_cls = BENCHMARKS.get(bench_name)
            if bench_cls is None:
                logger.warning(f"Unknown benchmark: {bench_name}")
                continue

            evaluator = bench_cls()

            # Load dataset
            await _send_event(run, {
                "type": "progress",
                "phase": "download",
                "model_id": request.model_id,
                "benchmark": bench_name,
                "message": f"Loading {bench_name} dataset...",
                "current": completed,
                "total": len(request.benchmarks),
            })

            try:
                items = await evaluator.load_dataset(sample_size=sample_size)
            except Exception as e:
                logger.error(f"Failed to load {bench_name} dataset: {e}")
                await _send_event(run, {
                    "type": "error",
                    "message": f"Failed to load {bench_name} dataset: {e}",
                })
                run.status = "error"
                run.error_message = str(e)
                return

            # Run evaluation with progress
            total_items = len(items)

            async def on_progress(current: int, total: int) -> None:
                if run.status == "cancelled":
                    raise asyncio.CancelledError()
                await _send_event(run, {
                    "type": "progress",
                    "phase": "eval",
                    "model_id": request.model_id,
                    "benchmark": bench_name,
                    "message": f"Evaluating {bench_name} ({current}/{total})...",
                    "current": completed,
                    "total": len(request.benchmarks),
                    "bench_current": current,
                    "bench_total": total,
                })

            await _send_event(run, {
                "type": "progress",
                "phase": "eval",
                "model_id": request.model_id,
                "benchmark": bench_name,
                "message": f"Evaluating {bench_name} (0/{total_items})...",
                "current": completed,
                "total": len(request.benchmarks),
                "bench_current": 0,
                "bench_total": total_items,
            })

            try:
                result = await evaluator.run(
                    engine, items, on_progress,
                    batch_size=request.batch_size,
                    sampling_kwargs=sampling_kwargs,
                    enable_thinking=request.enable_thinking,
                )
            except asyncio.CancelledError:
                run.status = "cancelled"
                await _send_event(run, {
                    "type": "error",
                    "message": "Benchmark cancelled",
                })
                return
            except Exception as e:
                logger.error(f"Error running {bench_name}: {e}")
                await _send_event(run, {
                    "type": "error",
                    "message": f"Error running {bench_name}: {e}",
                })
                run.status = "error"
                run.error_message = str(e)
                return

            question_results = []
            for qr in result.question_results:
                question_data = {
                    "id": qr.question_id,
                    "correct": qr.correct,
                    "expected": qr.expected,
                    "predicted": qr.predicted,
                    "question": qr.question_text,
                    "raw_response": qr.ra          ForEach(Array(results.enumerated()), id: \.element.id) { idx, result in
                    FreeRow(isLast: idx == results.count - 1) {
                        ResultCard(result: result)
                    }
                }
            }
        }
    }
}

private struct ResultCard: View {
    let result: AccuracyResultDTO

    @State private var categoriesOpen: Bool = false
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack(alignment: .firstTextBaseline, spacing: 12) {
                Text(percentText)
                    .font(.omlxText(22, weight: .semibold))
                    .foregroundStyle(accuracyColor)
                    .monospacedDigit()
                VStack(alignment: .leading, spacing: 3) {
                    HStack(spacing: 6) {
                        Text(benchmarkDisplay)
                            .font(.omlxText(13, weight: .medium))
                            .foregroundStyle(theme.text)
                        Pill(label: result.modelId, color: theme.blueDot)
                        if result.thinkingUsed {
                            Pill(label: String(localized: "bench.accuracy.result.thinking_pill",
                                               defaultValue: "Extended thinking",
                                               comment: "Pill on an Accuracy Bench result card when extended thinking was used"),
                                 color: Color(rgb24: 0x5E5CE6))
                        }
                    }
                    Text(subtitleText)
                        .font(.omlxMono(11))
                        .foregroundStyle(theme.textSecondary)
                }
                Spacer(minLength: 0)
            }

            if result.categoryScores?.isEmpty == false {
                Button {
                    withAnimation(.easeOut(duration: 0.15)) { categoriesOpen.toggle() }
                } label: {
                    HStack(spacing: 5) {
                        Image(systemName: categoriesOpen ? "chevron.down" : "chevron.right")
                            .font(.system(size: 9, weight: .semibold))
                        Text(String(localized: "bench.accuracy.result.categories",
                                    defaultValue: "Categories",
                                    comment: "Disclosure label on an Accuracy Bench result card revealing per-category breakdowns"))
                            .font(.omlxText(11, weight: .medium))
                    }
                    .foregroundStyle(theme.textSecondary)
                    .contentShape(Rectangle())
                }
                .buttonStyle(.plain)

                if categoriesOpen, let scores = result.categoryScores {
                    CategoriesTable(scores: scores)
                }
            }
        }
    }

    private var percentText: String {
        let pct = result.accuracy * 100
        return String(format: "%.1f%%", pct)
    }

    private var accuracyColor: Color {
        let pct = result.accuracy * 100
        if pct >= 70 { return theme.greenDot }
        if pct >= 40 { return theme.amberDot }
        return theme.redDot
    }

    private var benchmarkDisplay: String {
        benchmarkCatalog.first(where: { $0.key == result.benchmark })?.displayName
            ?? result.benchmark
    }

    private var subtitleText: String {
        let time = String(format: "%.1f s", result.timeS)
        return "\(result.correct) / \(result.total) · \(time)"
    }
}

private struct Pill: View {
    let label: String
    let color: Color

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        Text(label)
            .font(.omlxText(10, weight: .medium))
            .foregroundStyle(color)
            .lineLimit(1)
            .truncationMode(.middle)
            .padding(.horizontal, 6)
            .padding(.vertical, 1)
            .background(color.opacity(0.12))
            .clipShape(Capsule())
    }
}

private struct CategoriesTable: View {
    let scthinking_budget_tokens || null,
                    guided_grammar_enabled: s.guided_grammar_enabled || false,
                    guided_grammar: s.guided_grammar || '',
                    enableToolResultLimit: !!(s.max_tool_result_tokens),
                    max_tool_result_tokens: s.max_tool_result_tokens || null,
                    reasoning_parser: s.reasoning_parser || '',
                    ttl_seconds: s.ttl_seconds ?? null,
                    enableIndexCache: !!(s.index_cache_freq),
                    index_cache_freq: s.index_cache_freq || null,
                    turboquant_kv_enabled: s.turboquant_kv_enabled || false,
                    turboquant_kv_bits: s.turboquant_kv_bits || 4,
                    specprefill_enabled: s.specprefill_enabled || false,
                    specprefill_draft_model: s.specprefill_draft_model || '',
                    specprefill_keep_pct: s.specprefill_keep_pct ? String(s.specprefill_keep_pct) : '0.2',
                    specprefill_threshold: s.specprefill_threshold || null,
                    dflash_enabled: s.dflash_enabled || false,
                    dflash_draft_model: s.dflash_draft_model || '',
                    dflash_draft_quant_enabled: s.dflash_draft_quant_enabled || false,
                    dflash_draft_quant_weight_bits: s.dflash_draft_quant_weight_bits || 4,
                    dflash_draft_quant_activation_bits: s.dflash_draft_quant_activation_bits || 16,
                    dflash_draft_quant_group_size: s.dflash_draft_quant_group_size || 64,
                    dflash_max_ctx: s.dflash_max_ctx ?? null,
                    dflash_in_memory_cache: s.dflash_in_memory_cache !== false,
                    dflash_in_memory_cache_max_entries: s.dflash_in_memory_cache_max_entries || 4,
                    dflash_in_memory_cache_max_gib: s.dflash_in_memory_cache_max_bytes
                        ? Math.round(s.dflash_in_memory_cache_max_bytes / (1024 ** 3))
                        : 8,
                    dflash_ssd_cache: s.dflash_ssd_cache || false,
                    dflash_ssd_cache_max_gib: s.dflash_ssd_cache_max_bytes
                        ? Math.round(s.dflash_ssd_cache_max_bytes / (1024 ** 3))
                        : 20,
                    dflash_draft_window_size: s.dflash_draft_window_size ?? null,
                    dflash_draft_sink_size: s.dflash_draft_sink_size ?? null,
                    dflash_verify_mode: s.dflash_verify_mode || 'adaptive',
                    dflash_compatible: model?.dflash_compatible !== false,
                    dflash_compatibility_reason: model?.dflash_compatibility_reason || '',
                    dflash_ssd_cache_available: !!model?.dflash_ssd_cache_available,
                    mtp_enabled: s.mtp_enabled || false,
                    mtp_compatible: model?.mtp_compatible === true,
                    mtp_compatibility_reason: model?.mtp_compatibility_reason || '',
                    is_paroquant: model?.is_paroquant === true,
                    paroquant_reason: model?.paroquant_reason || '',
                    vlm_mtp_enabled: s.vlm_mtp_enabled || false,
                    vlm_mtp_draft_model: s.vlm_mtp_draft_model || '',
                    vlm_mtp_draft_block_size: s.vlm_mtp_draft_block_size ?? null,
                    ctKwargEntries,
                    is_diffusion_model: isDiffusion,
                    trust_remote_code: s.trust_remote_code || false,
                };
            },

            _resetPresetApplicableFields() {
                // Reset all fields a preset can touch so switching presets does not leave
                // stale values. Intentionally does NOT touch model_alias / model_type_override
                // / is_pinned / is_default / turboquant_* / dflash_* / specprefill_* / index_cache_*.
                const ms = this.modelSettings;
                ms.temperature = null;
                ms.top_p = null;
                ms.top_k = null;
                ms.min_p = null;
                ms.repetition_penalty = null;
                ms.presence_penalty = null;
  hs =
        static_cast<const DeepseekMxfp4GatherBlocksPrimitive&>(other);
    return variant_ == rhs.variant_;
  }
  auto state() const {
    return std::make_tuple(variant_);
  }

 private:
  int variant_;
};

class DeepseekMxfp4GatherPairBlocksPrimitive : public Primitive {
 public:
  explicit DeepseekMxfp4GatherPairBlocksPrimitive(
      Stream stream,
      int variant,
      bool concat_output = false)
      : Primitive(stream), variant_(variant), concat_output_(concat_output) {
    (void)mxfp4_blocks_variant(variant_);
  }

  static bool unsupported(
      const array& x,
      const array& weight0,
      const array& scales0,
      const array& weight1,
      const array& scales1,
      const array& block_meta,
      const array& block_count,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (x.dtype() != float16 && x.dtype() != bfloat16) {
      return true;
    }
    if (weight0.dtype() != uint32 || scales0.dtype() != uint8 ||
        weight1.dtype() != uint32 || scales1.dtype() != uint8 ||
        block_meta.dtype() != int32 || block_count.dtype() != int32) {
      return true;
    }
    if (x.ndim() != 3 || x.shape(1) != 1 || weight0.ndim() != 3 ||
        scales0.ndim() != 3 || weight1.ndim() != 3 || scales1.ndim() != 3 ||
        block_meta.ndim() != 2 || block_meta.shape(1) != 3 ||
        block_count.size() != 1) {
      return true;
    }
    if (!row_contiguous(x) || !row_contiguous(weight0) ||
        !row_contiguous(scales0) || !row_contiguous(weight1) ||
        !row_contiguous(scales1) || !row_contiguous(block_meta) ||
        !row_contiguous(block_count)) {
      return true;
    }

    constexpr int bits = 4;
    constexpr int group_size = 32;
    constexpr int values_per_uint32 = 32 / bits;
    const int K = x.shape(2);
    const int E = weight0.shape(0);
    const int N = weight0.shape(1);
    if (x.shape(0) <= 0 || K <= 0 || N <= 0 || E <= 0 ||
        block_meta.shape(0) <= 0) {
      return true;
    }
    if (weight1.shape() != weight0.shape() || scales1.shape() != scales0.shape()) {
      return true;
    }
    if (weight0.shape(2) * values_per_uint32 != K ||
        scales0.shape(0) != E || scales0.shape(1) != N ||
        scales0.shape(2) != K / group_size) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error(
        "DeepseekMxfp4GatherPairBlocksPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x = inputs[0];
    const auto& weight0 = inputs[1];
    const auto& scales0 = inputs[2];
    const auto& weight1 = inputs[3];
    const auto& scales1 = inputs[4];
    const auto& block_meta = inputs[5];
    const auto& block_count = inputs[6];

    out.set_data(allocator::malloc(out.nbytes()));

    const auto cfg = mxfp4_blocks_variant(variant_);
    const int max_blocks = block_meta.shape(0);
    const int M = x.shape(0);
    const int K = x.shape(2);
    const int N = weight0.shape(1);

    std::string kname;
    concatenate(
        kname,
        concat_output_ ? "deepseek_mxfp4_gather_pair_concat_blocks_rhs_"
                       : "deepseek_mxfp4_gather_pair_blocks_rhs_",
        glm_type_name(x.dtype()),
        "_bm_",
        cfg.bm,
        "_bn_",
        cfg.bn,
        "_bk_",
        cfg.bk,
        "_wm_",
        cfg.wm,
        "_wn_",
        cfg.wn);

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.set_compute_pipeline_state(kernel);
    compute_encoder.set_input_array(x, 0);
    compute_encoder.set_input_array(weight0, 1);
    compute_encoder.set_input_array(scales0, 2);
    compute_encoder.set_input_array(weight1, 3);
    compute_encoder.set_input_array(scales1, w_response,
                    "category": qr.category,
                    "time_s": round(qr.time_seconds, 3),
                }
                if request.external is not None:
                    question_data.update({
                        "status": qr.status,
                        "finish_reason": qr.finish_reason,
                        "reasoning_fields_present": qr.reasoning_fields_present,
                        "reasoning_fields_nonempty": qr.reasoning_fields_nonempty,
                        "prompt_tokens": qr.prompt_tokens,
                        "completion_tokens": qr.completion_tokens,
                        "error_message": qr.error_message,
                    })
                question_results.append(question_data)

            result_data = {
                "model_id": request.model_id,
                "external": request.external is not None,
                "benchmark": result.benchmark_name,
                "accuracy": round(result.accuracy, 4),
                "thinking_used": result.thinking_used,
                "total": result.total_questions,
                "correct": result.correct_count,
                "time_s": round(result.time_seconds, 1),
                "question_results": question_results,
            }
            if request.external is not None:
                status_counts = Counter(
                    qr.status or "invalid_response" for qr in result.question_results
                )
                valid_responses = status_counts["correct"] + status_counts["wrong"]
                total_questions = result.total_questions
                result_data.update({
                    "valid_response_count": valid_responses,
                    "empty_content_count": status_counts["empty_content"],
                    "truncated_count": status_counts["truncated"],
                    "timeout_count": status_counts["timeout"],
                    "http_error_count": status_counts["http_error"],
                    "connection_error_count": status_counts["connection_error"],
                    "invalid_response_count": status_counts["invalid_response"],
                    "parse_error_count": status_counts["parse_error"],
                    "wrong_count": status_counts["wrong"],
                    "valid_response_rate": round(
                        valid_responses / total_questions
                        if total_questions > 0 else 0.0,
                        4,
                    ),
                    "valid_answer_accuracy": round(
                        result.correct_count / valid_responses
                        if valid_responses > 0 else 0.0,
                        4,
                    ),
                    "reliability_warning": any(
                        status_counts[name] > 0
                        for name in (
                            "empty_content",
                            "truncated",
                            "timeout",
                            "http_error",
                            "connection_error",
                            "invalid_response",
                            "parse_error",
                        )
                    ),
                })
            if result.category_scores:
                result_data["category_scores"] = {
                    k: round(v, 4) for k, v in result.category_scores.items()
                }

            # Accumulate persistently
            _accumulated_results.append(result_data)

            run.results.append(result_data)
            completed += 1

            await _send_event(run, {
                "type": "result",
                "data": result_data,
            })

        # Phase 4: Unload model. The result(s) are already emitted by now,
        # so flip phase so polling clients hide the running indicator
        # (the result card has already appeared on screen — telling the
        # user "still running" while we clean up reads as a bug).
        run.phase = "unloading"
        if request.external is None:
            try:
                await engine_pool._unloores: [String: Double]

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        let entries = scores.sorted { $0.value > $1.value }
        VStack(spacing: 0) {
            ForEach(Array(entries.enumerated()), id: \.element.key) { idx, pair in
                HStack(spacing: 10) {
                    Text(pair.key)
                        .font(.omlxText(11))
                        .foregroundStyle(theme.textSecondary)
                        .lineLimit(1)
                        .truncationMode(.tail)
                    Spacer(minLength: 8)
                    Text(String(format: "%.1f%%", pair.value * 100))
                        .font(.omlxMono(11))
                        .foregroundStyle(theme.text)
                        .monospacedDigit()
                }
                .padding(.horizontal, 10)
                .padding(.vertical, 5)
                .overlay(alignment: .bottom) {
                    if idx < entries.count - 1 {
                        Rectangle()
                            .fill(theme.rowSep)
                            .frame(height: 0.5)
                            .padding(.leading, 10)
                    }
                }
            }
        }
        .background(theme.codeBg)
        .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
    }
}

// MARK: - Text export

private struct TextExportSection: View {
    let results: [AccuracyResultDTO]

    @State private var isOpen: Bool = false
    @State private var copied: Bool = false
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        SectionHeader(String(localized: "bench.accuracy.section.text_export",
                             defaultValue: "Text Export",
                             comment: "Section header for the Accuracy Bench text-export block"))

        ListGroup {
            FreeRow(isLast: true) {
                VStack(alignment: .leading, spacing: 8) {
                    HStack(spacing: 8) {
                        Button {
                            withAnimation(.easeOut(duration: 0.15)) { isOpen.toggle() }
                        } label: {
                            HStack(spacing: 5) {
                                Image(systemName: isOpen ? "chevron.down" : "chevron.right")
                                    .font(.system(size: 9, weight: .semibold))
                                Text(isOpen
                                     ? String(localized: "bench.accuracy.text_export.hide",
                                              defaultValue: "Hide text dump",
                                              comment: "Disclosure label that hides the Accuracy Bench text export")
                                     : String(localized: "bench.accuracy.text_export.show",
                                              defaultValue: "Show text dump",
                                              comment: "Disclosure label that reveals the Accuracy Bench text export"))
                                    .font(.omlxText(11, weight: .medium))
                            }
                            .foregroundStyle(theme.textSecondary)
                            .contentShape(Rectangle())
                        }
                        .buttonStyle(.plain)
                        Spacer(minLength: 0)
                        Button {
                            copyToClipboard()
                        } label: {
                            Label(copied
                                  ? String(localized: "bench.accuracy.text_export.copied",
                                           defaultValue: "Copied",
                                           comment: "Transient confirmation label after copying the Accuracy Bench text dump")
                                  : String(localized: "common.copy",
                                           defaultValue: "Copy",
                                           comment: "Generic Copy button label"),
                                  systemImage: copied ? "checkmark" : "document.on.document")
                   ms.force_sampling = false;
                ms.max_context_window = null;
                ms.max_tokens = null;
                ms.reasoning_parser = null;
                ms.guided_grammar_enabled = false;
                ms.guided_grammar = '';
                ms.ttl_seconds = null;
                ms.enable_thinking = null;
                ms.enableThinkingBudget = false;
                ms.thinking_budget_tokens = null;
                ms.enableToolResultLimit = false;
                ms.max_tool_result_tokens = null;
                ms.ctKwargEntries = [];
            },

            applyPresetToForm(preset) {
                // Reset first so previous preset's fields (e.g. presence_penalty) do not stick.
                this._resetPresetApplicableFields();
                const s = preset.settings || {};
                const ms = this.modelSettings;
                const isDiffusion = !!ms.is_diffusion_model;
                for (const k of Object.keys(s)) {
                    if (isDiffusion
                        && k !== 'chat_template_kwargs'
                        && k !== 'forced_ct_kwargs'
                        && this.isDiffusionUnsupportedProfileField(k)) {
                        continue;
                    }
                    if (k === 'thinking_budget_enabled') {
                        ms.enableThinkingBudget = !!s[k];
                    } else if (k === 'max_tool_result_tokens') {
                        ms.enableToolResultLimit = s[k] != null;
                        ms.max_tool_result_tokens = s[k] ?? null;
                    } else if (k === 'guided_grammar_enabled') {
                        ms.guided_grammar_enabled = !!s[k];
                    } else if (k === 'guided_grammar') {
                        ms.guided_grammar = s[k] || '';
                    } else if (k === 'chat_template_kwargs' || k === 'forced_ct_kwargs') {
                        ms.ctKwargEntries = this.buildCtKwargEntries(
                            s.chat_template_kwargs,
                            s.forced_ct_kwargs,
                            isDiffusion,
                        );
                    } else {
                        ms[k] = s[k];
                    }
                }
                this.activeProfileName = null;
                this.profilesDrift = false;
            },

            setScope(scope) {
                this.profileScope = scope;
                try { localStorage.setItem('omlx_profile_scope', scope); } catch (e) {}
            },

            isValidProfileName(name) {
                // Mirror of the backend rule (validate_profile_name) and the
                // Mac app's isValidSlug. api_name is the exposed model ID
                // suffix (<model>:<api_name>), so it must be a clean slug.
                return /^[a-z0-9][a-z0-9_-]{0,31}$/.test((name || '').trim());
            },
            slugifyProfileApiName(value) {
                let slug = (value || '')
                    .normalize('NFKD')
                    .replace(/[\u0300-\u036f]/g, '')
                    .toLowerCase()
                    .replace(/[^a-z0-9_-]+/g, '-')
                    .replace(/-+/g, '-')
                    .replace(/^[-_]+|[-_]+$/g, '')
                    .slice(0, 32)
                    .replace(/[-_]+$/g, '');
                return slug || 'profile';
            },
            async createProfile() {
                if (!this.selectedModel) return;
                this.profileError = '';
                const displayName = (this.newProfile.display_name || '').trim();
                if (!displayName) {
                    this.profileError = 'Name required';
                    return;
                }
                const apiName = (this.newProfile.api_name || this.slugifyProfileApiName(displayName)).trim();
                if (!this.isValidProfileName(apiName)) {
                    this.profileError = window.t('modal.model_settings.profiles.invalid_name');
                    return;
                }
                const autoId = 'p-' + Date.now().toS4);
    compute_encoder.set_input_array(block_meta, 5);
    compute_encoder.set_input_array(block_count, 6);
    compute_encoder.set_output_array(out, 7);
    compute_encoder.set_bytes(max_blocks, 8);
    compute_encoder.set_bytes(M, 9);
    compute_encoder.set_bytes(N, 10);
    compute_encoder.set_bytes(K, 11);

    const int grid_n = concat_output_ ? 2 * N : N;
    MTL::Size grid_dims(
        (grid_n + cfg.bn - 1) / cfg.bn,
        max_blocks,
        concat_output_ ? 1 : 2);
    MTL::Size group_dims(cfg.wm * cfg.wn * 32, 1, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(DeepseekMxfp4GatherPairBlocksPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs =
        static_cast<const DeepseekMxfp4GatherPairBlocksPrimitive&>(other);
    return variant_ == rhs.variant_ && concat_output_ == rhs.concat_output_;
  }
  auto state() const {
    return std::make_tuple(variant_, concat_output_);
  }

 private:
  int variant_;
  bool concat_output_;
};

class DeepseekAffineGatherBlocksPrimitive : public Primitive {
 public:
  explicit DeepseekAffineGatherBlocksPrimitive(
      Stream stream,
      int group_size,
      int bits,
      int variant)
      : Primitive(stream),
        group_size_(group_size),
        bits_(bits),
        variant_(variant) {
    (void)mxfp4_blocks_variant(variant_);
    if (!supported_deepseek_affine(group_size_, bits_)) {
      throw std::invalid_argument(
          "Unsupported DeepSeek affine block-list quantization.");
    }
  }

  static bool unsupported(
      const array& x,
      const array& weight,
      const array& scales,
      const array& biases,
      const array& block_meta,
      const array& block_count,
      int group_size,
      int bits,
      Stream s) {
    if (s.device == Device::cpu || !supported_deepseek_affine(group_size, bits)) {
      return true;
    }
    if (x.dtype() != float16 && x.dtype() != bfloat16) {
      return true;
    }
    if (weight.dtype() != uint32 || scales.dtype() != x.dtype() ||
        biases.dtype() != x.dtype() || block_meta.dtype() != int32 ||
        block_count.dtype() != int32) {
      return true;
    }
    if (x.ndim() != 3 || x.shape(1) != 1 || weight.ndim() != 3 ||
        scales.ndim() != 3 || biases.ndim() != 3 || block_meta.ndim() != 2 ||
        block_meta.shape(1) != 3 || block_count.size() != 1) {
      return true;
    }
    if (!row_contiguous(x) || !row_contiguous(weight) ||
        !row_contiguous(scales) || !row_contiguous(biases) ||
        !row_contiguous(block_meta) || !row_contiguous(block_count)) {
      return true;
    }

    const int K = x.shape(2);
    const int E = weight.shape(0);
    const int N = weight.shape(1);
    const int packed_bytes = affine_packed_row_bytes(K, bits);
    if (x.shape(0) <= 0 || K <= 0 || N <= 0 || E <= 0 ||
        block_meta.shape(0) <= 0 || packed_bytes <= 0) {
      return true;
    }
    if (weight.shape(2) * static_cast<int>(sizeof(uint32_t)) != packed_bytes ||
        scales.shape(0) != E || scales.shape(1) != N ||
        scales.shape(2) != K / group_size || biases.shape() != scales.shape()) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error(
        "DeepseekAffineGatherBlocksPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x = inputs[0];
    const auto& weight = inputs[1];
    const auto& scales = inputs[2];
    const auto& biases = inputs[3];
    const auto& block_meta = inputs[4];
    const auto& block_count = inputs[5];

    out.set_data(allocator::malloc(out.nbytes()));

    const auto cfg = mxfp4_blocks_variant(variant_);
    const int max_blocks = block_meta.shape(0);
    const int M = x.shape(0);
    const int K = x.shape(2);
    consad_engine(request.model_id)
            except Exception:
                pass

        # Phase 5: Done
        total_time = time.time() - start_time
        run.status = "completed"
        run.phase = "completed"

        await _send_event(run, {
            "type": "done",
            "summary": {
                "model_id": request.model_id,
                "total_time": round(total_time, 1),
                "benchmarks_completed": completed,
            },
        })

    except asyncio.CancelledError:
        run.status = "cancelled"
        run.phase = "cancelled"
        await _send_event(run, {
            "type": "error",
            "message": "Benchmark cancelled",
        })
    except Exception as e:
        logger.exception(f"Accuracy benchmark error: {e}")
        run.status = "error"
        run.phase = "error"
        run.error_message = str(e)
        await _send_event(run, {
            "type": "error",
            "message": str(e),
        })
    finally:
        # Re-enable TTL auto-unload
        engine_pool._suppress_ttl = False
        if client is not None:
            await client.aclose()


# ===== FILE: omlx/admin/auth.py =====

# SPDX-License-Identifier: Apache-2.0
"""Authentication utilities for the oMLX admin panel.

This module provides session-based authentication using signed tokens
and API key verification for admin panel access.
"""

import hashlib
import os
import secrets
from typing import Optional

from fastapi import HTTPException, Request
from fastapi.responses import RedirectResponse
from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer

# Session configuration
SESSION_COOKIE_NAME = "omlx_admin_session"
SESSION_MAX_AGE = 86400  # 24 hours in seconds
REMEMBER_ME_MAX_AGE = 2592000  # 30 days in seconds

# Secret key for signing session tokens
# Use environment variable if set, otherwise generate a random key
# Note: Random key means sessions won't persist across server restarts
# This is a fallback; init_auth() should be called with a persistent key
SECRET_KEY = os.environ.get("OMLX_SECRET_KEY") or secrets.token_hex(32)

# Initialize the serializer for creating and verifying session tokens
_serializer = URLSafeTimedSerializer(SECRET_KEY)

# Global settings getter (set by init_auth)
_get_global_settings = None


def init_auth(secret_key: str, global_settings_getter=None) -> None:
    """Initialize authentication with a persistent secret key.

    Should be called during server startup with the secret key from settings.
    Environment variable OMLX_SECRET_KEY takes priority if set.

    Args:
        secret_key: The secret key from settings.json for signing tokens.
        global_settings_getter: Optional callable that returns GlobalSettings.
    """
    global _serializer, SECRET_KEY, _get_global_settings
    # Environment variable takes priority over settings
    key = os.environ.get("OMLX_SECRET_KEY") or secret_key
    SECRET_KEY = key
    _serializer = URLSafeTimedSerializer(key)
    if global_settings_getter is not None:
        _get_global_settings = global_settings_getter


def create_session_token(remember: bool = False) -> str:
    """Create a signed session token for admin authentication.

    Args:
        remember: If True, the token payload includes a remember flag
                  for extended session duration (30 days).

    Returns:
        A URL-safe signed token string containing admin session data.

    Example:
        >>> token = create_session_token()
        >>> verify_session_token(token)
        True
    """
    payload = {"admin": True, "remember": remember}
    return _serializer.dumps(payload)


def verify_session_token(token: str, max_age: int = SESSION_MAX_AGE) -> bool:
    """Verify and decode a session token.

    The max_age is determined by the token's remember flag:
    - remember=True: 30 days
    - remember=False (default): 24 hours

    Args:
        token: The signed session token to verify.
        max_age: Maximum age of the token in seconds. Defaults to 24 hours.
                 This is overridden by the token's                           .labelStyle(.titleAndIcon)
                        }
                        .buttonStyle(.omlx(.normal, size: .small))
                    }
                    if isOpen {
                        ScrollView {
                            Text(textDump)
                                .font(.omlxMono(11))
                                .foregroundStyle(theme.text)
                                .frame(maxWidth: .infinity, alignment: .leading)
                                .padding(8)
                                .textSelection(.enabled)
                        }
                        .frame(maxHeight: 180)
                        .background(theme.codeBg)
                        .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
                    }
                }
            }
        }
        .padding(.bottom, 18)
    }

    private var textDump: String {
        results.map { r in
            let pct = String(format: "%.1f%%", r.accuracy * 100)
            let time = String(format: "%.1f s", r.timeS)
            return "\(r.benchmark) · \(r.modelId) · \(pct) (\(r.correct)/\(r.total)) · \(time)"
        }.joined(separator: "\n")
    }

    private func copyToClipboard() {
        let pb = NSPasteboard.general
        pb.clearContents()
        pb.setString(textDump, forType: .string)
        copied = true
        Task {
            try? await Task.sleep(for: .seconds(1.5))
            await MainActor.run { copied = false }
        }
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/AppearanceScreen.swift =====

// Appearance pane: menubar refresh cadence, the Dock-icon override, and the
// per-metric menubar item toggles. Everything here is app-local UserDefaults
// (settings.json is server-owned); the menubar controller and AppDelegate
// pick changes up through the UserDefaults change notification, so the
// screen needs no view model and no onChange plumbing.

import SwiftUI

struct AppearanceScreen: View {
    @AppStorage(MenubarMetricPrefs.refreshIntervalKey)
    private var refreshInterval = 1.0
    @AppStorage(MenubarMetricPrefs.showDockIconKey)
    private var showDockIcon = false
    @AppStorage(MenubarMetricPrefs.liveKey)
    private var showLiveActivity = false
    @AppStorage(MenubarMetricPrefs.averageKey)
    private var showAverageActivity = false
    @AppStorage(MenubarMetricPrefs.alltimeKey)
    private var showAlltimeActivity = false
    @AppStorage(MenubarMetricPrefs.cpuItemKey)
    private var showCPUItem = false
    @AppStorage(MenubarMetricPrefs.gpuItemKey)
    private var showGPUItem = false
    @AppStorage(MenubarMetricPrefs.memoryItemKey)
    private var showMemoryItem = false
    @AppStorage(MenubarMetricPrefs.modelLibraryScopeKey)
    private var modelLibraryScope = MenuBarModelScope.all.rawValue

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            SectionHeader(String(
                localized: "appearance.section.general",
                defaultValue: "General",
                comment: "Appearance screen section header for the basic options"
            ))
            ListGroup {
                Row(
                    label: String(
                        localized: "appearance.row.refresh_interval",
                        defaultValue: "Refresh Interval",
                        comment: "Appearance row label for the menubar refresh cadence picker"
                    ),
                    sublabel: String(
                        localized: "appearance.row.refresh_interval.sub",
                        defaultValue: "How often menu bar items and their graphs update.",
                        comment: "Appearance row sublabel for the menubar refresh cadence picker"
                    )
                ) {
                    Popup(selection: $refreshInterval, width: 110, options: [
                        (0.5, "0.5 s"),
                        (1.0, "1 s"),
                        (2.0, "2 s"),
                        (3.0, "3 s"),
                    ])
                }
      tring(36) + '-' +
                               Math.random().toString(36).slice(2, 6);
                const body = {
                    name: autoId,
                    display_name: displayName,
                    api_name: apiName,
                    description: (this.newProfile.description || '').trim() || null,
                    settings: this.formValuesForProfile(),
                    also_save_as_template: false,
                };
                try {
                    const r = await fetch(
                        `/admin/api/models/${encodeURIComponent(this.selectedModel.id)}/profiles`,
                        { method: 'POST', headers: {'Content-Type': 'application/json'},
                          body: JSON.stringify(body) }
                    );
                    if (r.ok) {
                        await this.loadProfilesForModel(this.selectedModel.id);
                        if (body.also_save_as_template) await this.loadTemplates();
                        this.showNewProfileForm = false;
                        this.newProfile = { display_name: '', api_name: '', api_name_touched: false, description: '', also_as_template: false };
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await r.json().catch(() => ({}));
                        this.profileError = data.detail || 'Failed to save profile';
                    }
                } catch (e) {
                    this.profileError = String(e);
                }
            },
            async applyProfileToForm(profile) {
                const seq = ++this._applySeq;
                try {
                    const r = await fetch(
                        `/admin/api/models/${encodeURIComponent(this.selectedModel.id)}/profiles/${encodeURIComponent(profile.name)}/apply`,
                        { method: 'POST' }
                    );
                    if (seq !== this._applySeq) return;  // superseded by a newer click
                    if (r.ok) {
                        const data = await r.json();
                        const activeName = data.settings?.active_profile_name || profile.name;
                        const settings = {
                            ...(data.settings || {}),
                            active_profile_name: activeName,
                        };
                        this.modelSettings = this.buildModelSettingsState(
                            this.selectedModel,
                            settings,
                        );
                        if (this.selectedModel) {
                            this.selectedModel.settings = { ...settings };
                        }
                        this.activeProfileName = activeName;
                        this.profilesDrift = false;
                        // Update the models list so the profile badge reflects the change
                        const m = this.models.find(m => m.id === this.selectedModel.id);
                        if (m) m.settings = { ...settings };
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (e) {
                    console.error('Failed to apply profile:', e);
                }
            },
            async applyTemplateToForm(template) {
                // Check if a profile with this template's name already exists
                const existingProfile = this.profiles.find(p => p.name === template.name);

                if (existingProfile) {
                    // Global templates are the source of truth in this scope.
                    const updatedProfile = await this.updateProfile(existingProfile.name, {
                        settings: template.settings,
                        source_template: template.name,
                    });
                    if (updatedProfile) {
                        await this.applyProfileToForm(updatedProfile);
                    }
               t int N = weight.shape(1);

    std::string kname;
    concatenate(
        kname,
        "deepseek_affine_gather_blocks_rhs_",
        glm_type_name(x.dtype()),
        "_gs_",
        group_size_,
        "_b_",
        bits_,
        "_bm_",
        cfg.bm,
        "_bn_",
        cfg.bn,
        "_bk_",
        cfg.bk,
        "_wm_",
        cfg.wm,
        "_wn_",
        cfg.wn);

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.set_compute_pipeline_state(kernel);
    compute_encoder.set_input_array(x, 0);
    compute_encoder.set_input_array(weight, 1);
    compute_encoder.set_input_array(scales, 2);
    compute_encoder.set_input_array(biases, 3);
    compute_encoder.set_input_array(block_meta, 4);
    compute_encoder.set_input_array(block_count, 5);
    compute_encoder.set_output_array(out, 6);
    compute_encoder.set_bytes(max_blocks, 7);
    compute_encoder.set_bytes(M, 8);
    compute_encoder.set_bytes(N, 9);
    compute_encoder.set_bytes(K, 10);

    MTL::Size grid_dims((N + cfg.bn - 1) / cfg.bn, max_blocks, 1);
    MTL::Size group_dims(cfg.wm * cfg.wn * 32, 1, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(DeepseekAffineGatherBlocksPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs =
        static_cast<const DeepseekAffineGatherBlocksPrimitive&>(other);
    return group_size_ == rhs.group_size_ && bits_ == rhs.bits_ &&
        variant_ == rhs.variant_;
  }
  auto state() const {
    return std::make_tuple(group_size_, bits_, variant_);
  }

 private:
  int group_size_;
  int bits_;
  int variant_;
};

class DeepseekAffineGatherPairBlocksPrimitive : public Primitive {
 public:
  explicit DeepseekAffineGatherPairBlocksPrimitive(
      Stream stream,
      int group_size,
      int bits,
      int variant)
      : Primitive(stream),
        group_size_(group_size),
        bits_(bits),
        variant_(variant) {
    (void)mxfp4_blocks_variant(variant_);
    if (!supported_deepseek_affine(group_size_, bits_)) {
      throw std::invalid_argument(
          "Unsupported DeepSeek affine pair block-list quantization.");
    }
  }

  static bool unsupported(
      const array& x,
      const array& weight0,
      const array& scales0,
      const array& biases0,
      const array& weight1,
      const array& scales1,
      const array& biases1,
      const array& block_meta,
      const array& block_count,
      int group_size,
      int bits,
      Stream s) {
    if (s.device == Device::cpu || !supported_deepseek_affine(group_size, bits)) {
      return true;
    }
    if (x.dtype() != float16 && x.dtype() != bfloat16) {
      return true;
    }
    if (weight0.dtype() != uint32 || weight1.dtype() != uint32 ||
        scales0.dtype() != x.dtype() || scales1.dtype() != x.dtype() ||
        biases0.dtype() != x.dtype() || biases1.dtype() != x.dtype() ||
        block_meta.dtype() != int32 || block_count.dtype() != int32) {
      return true;
    }
    if (x.ndim() != 3 || x.shape(1) != 1 || weight0.ndim() != 3 ||
        scales0.ndim() != 3 || biases0.ndim() != 3 || weight1.ndim() != 3 ||
        scales1.ndim() != 3 || biases1.ndim() != 3 || block_meta.ndim() != 2 ||
        block_meta.shape(1) != 3 || block_count.size() != 1) {
      return true;
    }
    if (!row_contiguous(x) || !row_contiguous(weight0) ||
        !row_contiguous(scales0) || !row_contiguous(biases0) ||
        !row_contiguous(weight1) || !row_contiguous(scales1) ||
        !row_contiguous(biases1) || !row_contiguous(block_meta) ||
        !row_contiguous(block_count)) {
      return true;
    }

    const int K = x.shape(2);
    const int E = weight0.shape(0);
    const int N = weight0.shape(1);
    const int packed_bytes = affine_packed_row_bytes(K, bits);
    if (x.shape(0) <= 0 || K <= 0 || N <= 0 || E <= 0 ||
        block_meta.shape(0) <= 0 || packed_bytes <= 0) {
      return true;
 remember flag.

    Returns:
        True if the token is valid and not expired, False otherwise.

    Example:
        >>> token = create_session_token()
        >>> verify_session_token(token)
        True
        >>> verify_session_token("invalid_token")
        False
    """
    try:
        # First load without max_age check to read the remember flag
        data = _serializer.loads(token, max_age=None)
        if data.get("admin", False) is not True:
            return False

        # Determine the appropriate max_age based on remember flag
        effective_max_age = (
            REMEMBER_ME_MAX_AGE if data.get("remember", False) else max_age
        )

        # Re-validate with the correct max_age
        data = _serializer.loads(token, max_age=effective_max_age)
        return data.get("admin", False) is True
    except (BadSignature, SignatureExpired):
        return False


def compare_keys(provided_key: str, expected_key: str) -> bool:
    """Compare two API keys in constant time, tolerating any str input.

    secrets.compare_digest raises TypeError when given str arguments that
    contain non-ASCII characters, which turns a bad client key into an
    unhandled 500 instead of a 401. Comparing UTF-8 bytes accepts any
    input while keeping the constant-time guarantee. surrogatepass covers
    lone surrogates, which json.loads can produce from escape sequences
    and which strict UTF-8 encoding rejects.

    Both arguments must be str; None is the caller's responsibility.

    Args:
        provided_key: The key supplied by the client (untrusted).
        expected_key: The configured key to compare against.

    Returns:
        True if the keys match, False otherwise.
    """
    return secrets.compare_digest(
        provided_key.encode("utf-8", "surrogatepass"),
        expected_key.encode("utf-8", "surrogatepass"),
    )


def fingerprint_key(api_key: str) -> str:
    """Return a short, non-reversible fingerprint of an API key for logging.

    Logging a rejected key verbatim leaks the client's secret into the server
    log. A truncated SHA-256 digest lets operators correlate repeated
    rejections of the same key without exposing the key itself. surrogatepass
    matches compare_keys() so any str the auth path accepts can be
    fingerprinted, including lone surrogates from json escape sequences.

    Args:
        api_key: The (untrusted) key to fingerprint. Empty string is allowed.

    Returns:
        The first 8 hex characters of the SHA-256 digest of the UTF-8 bytes.
    """
    digest = hashlib.sha256(api_key.encode("utf-8", "surrogatepass")).hexdigest()
    return digest[:8]


def verify_api_key(api_key: str, server_api_key: str) -> bool:
    """Verify an API key using constant-time comparison.

    This function uses constant-time comparison to prevent timing attacks
    when comparing the provided API key with the server's API key.

    Args:
        api_key: The API key provided by the client.
        server_api_key: The server's configured API key.

    Returns:
        True if the API keys match, False otherwise.

    Example:
        >>> verify_api_key("secret123", "secret123")
        True
        >>> verify_api_key("wrong", "secret123")
        False
    """
    if not api_key or not server_api_key:
        return False
    return compare_keys(api_key, server_api_key)


def verify_any_api_key(api_key: str, main_key: str, sub_keys: list) -> bool:
    """Verify an API key against the main key and all sub keys.

    Uses constant-time comparison for each key to prevent timing attacks.
    Checks the main key first, then iterates through sub keys.

    Args:
        api_key: The API key provided by the client.
        main_key: The server's main API key.
        sub_keys: List of SubKeyEntry objects with .key attribute.

    Returns:
        True if the API key matches any configured key, False otherwise.
    """
    if not api_key:
        return False
    # Check main key
    if main_key and compare_keys(api_key, main_key):
        return True
    # Check sub keys
    for sk in sub_          Row(
                    label: String(
                        localized: "appearance.row.show_dock_icon",
                        defaultValue: "Show Dock Icon",
                        comment: "Appearance row label for the permanent Dock icon toggle"
                    ),
                    sublabel: String(
                        localized: "appearance.row.show_dock_icon.sub",
                        defaultValue: "Keep the Dock icon visible even when no window is open.",
                        comment: "Appearance row sublabel for the permanent Dock icon toggle"
                    )
                ) {
                    Toggle("", isOn: $showDockIcon)
                        .labelsHidden()
                        .toggleStyle(.switch)
                }
                // Sits right under the Dock toggle because that's where people
                // look for it — the Dock icon and the menu bar icon read as one
                // pair, and "Show Dock Icon" was being clicked in the hope it
                // would bring the menu bar icon back (#2368).
                Row(
                    label: String(
                        localized: "appearance.row.menubar_icon",
                        defaultValue: "Menu Bar Icon",
                        comment: "Appearance row label for the menu bar icon restore action"
                    ),
                    sublabel: String(
                        localized: "appearance.row.menubar_icon.sub",
                        defaultValue: "Bring the oMLX icon back if it was removed from the menu bar. Separate from the Dock icon.",
                        comment: "Appearance row sublabel for the menu bar icon restore action"
                    ),
                    isLast: true
                ) {
                    Button {
                        NotificationCenter.default.post(
                            name: MenubarController.restoreIconRequestNotification,
                            object: nil
                        )
                    } label: {
                        Text(String(
                            localized: "appearance.row.menubar_icon.restore",
                            defaultValue: "Restore",
                            comment: "Appearance button title that restores the menu bar icon"
                        ))
                    }
                    .buttonStyle(.omlx(.normal, size: .small))
                }
            }

            SectionHeader(String(
                localized: "appearance.section.model_library",
                defaultValue: "Menu Bar Model Library",
                comment: "Appearance screen section header for the Models submenu scope"
            ))
            .padding(.top, 18)
            ListGroup {
                Row(
                    label: String(
                        localized: "appearance.row.visible_models",
                        defaultValue: "Visible Models",
                        comment: "Appearance row label for the Models submenu scope picker"
                    ),
                    sublabel: String(
                        localized: "appearance.row.visible_models.sub",
                        defaultValue: "Which models the menu bar Models menu lists. Loaded models always show.",
                        comment: "Appearance row sublabel for the Models submenu scope picker"
                    ),
                    isLast: true
                ) {
                    Segmented(selection: $modelLibraryScope, options: [
                        (
                            MenuBarModelScope.favoritesOnly.rawValue,
                            String(
                                localized: "appearance.model_scope.favorites",
                                defaultValue: "Favorites Only",
                                comment: "Models submenu scope option that lists only favorite models"
                            )
                        ),
                        (
                            MenuBarModelScope.all.rawValue,
                            Stri } else {
                    // Create a new profile from the template
                    const body = {
                        name: template.name,
                        display_name: template.display_name,
                        api_name: this.slugifyProfileApiName(template.display_name || template.name),
                        description: template.description || null,
                        settings: template.settings,
                        source_template: template.name,
                    };

                    try {
                        const r = await fetch(
                            `/admin/api/models/${encodeURIComponent(this.selectedModel.id)}/profiles`,
                            { method: 'POST', headers: {'Content-Type': 'application/json'},
                              body: JSON.stringify(body) }
                        );
                        if (r.ok) {
                            // Reload profiles first to include the new one
                            await this.loadProfilesForModel(this.selectedModel.id);
                            // Find the newly created profile in the refreshed list
                            const newProfile = this.profiles.find(p => p.name === template.name);
                            if (newProfile) {
                                await this.applyProfileToForm(newProfile);
                            }
                        }
                    } catch (e) {
                        console.error('Failed to create profile from template:', e);
                    }
                }
            },
            async deleteProfile(name) {
                if (!this.selectedModel) return;
                try {
                    const r = await fetch(
                        `/admin/api/models/${encodeURIComponent(this.selectedModel.id)}/profiles/${encodeURIComponent(name)}`,
                        { method: 'DELETE' }
                    );
                    if (r.ok) {
                        if (this.activeProfileName === name) this.activeProfileName = null;
                        await this.loadProfilesForModel(this.selectedModel.id);
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (e) {
                    console.error('Delete profile failed:', e);
                } finally {
                    this.profileDeleteConfirm = null;
                }
            },
            updateProfileFromEdit(p) {
                // Edit-dialog save. Internal profile name stays stable; api_name
                // is the API-visible suffix used by exposed model IDs.
                this.profileError = '';
                const displayName = (p._editDisplayName ?? p.display_name ?? p.name).trim();
                const apiName = (p._editApiName ?? p.api_name ?? p.name).trim();
                const description = (p._editDescription ?? p.description ?? '').trim();
                const exposeAsModel = !!(p._editExposeAsModel ?? p.expose_as_model);
                if (!displayName) {
                    this.profileError = 'Name required';
                    return;
                }
                if (!this.isValidProfileName(apiName)) {
                    this.profileError = window.t('modal.model_settings.profiles.invalid_name');
                    return;
                }
                const patch = {
                    display_name: displayName,
                    api_name: apiName,
                    description: description,
                    expose_as_model: exposeAsModel,
                };
                return this.updateProfile(p.name, patch);
            },
            updateProfileSettingsFromForm(p) {
                return this.updateProfile(p.name, {
                    settings: this.formValuesForProfile(),
                });
            },
            async updateProfile(name, patch) {
                // patch: { new_name?, display_name?, api_name?, description?, expose_as_model?, settings?, also_save_a    }
    if (weight1.shape() != weight0.shape() || scales1.shape() != scales0.shape() ||
        biases1.shape() != biases0.shape()) {
      return true;
    }
    if (weight0.shape(2) * static_cast<int>(sizeof(uint32_t)) != packed_bytes ||
        scales0.shape(0) != E || scales0.shape(1) != N ||
        scales0.shape(2) != K / group_size ||
        biases0.shape() != scales0.shape()) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error(
        "DeepseekAffineGatherPairBlocksPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x = inputs[0];
    const auto& weight0 = inputs[1];
    const auto& scales0 = inputs[2];
    const auto& biases0 = inputs[3];
    const auto& weight1 = inputs[4];
    const auto& scales1 = inputs[5];
    const auto& biases1 = inputs[6];
    const auto& block_meta = inputs[7];
    const auto& block_count = inputs[8];

    out.set_data(allocator::malloc(out.nbytes()));

    const auto cfg = mxfp4_blocks_variant(variant_);
    const int max_blocks = block_meta.shape(0);
    const int M = x.shape(0);
    const int K = x.shape(2);
    const int N = weight0.shape(1);

    std::string kname;
    concatenate(
        kname,
        "deepseek_affine_gather_pair_concat_blocks_rhs_",
        glm_type_name(x.dtype()),
        "_gs_",
        group_size_,
        "_b_",
        bits_,
        "_bm_",
        cfg.bm,
        "_bn_",
        cfg.bn,
        "_bk_",
        cfg.bk,
        "_wm_",
        cfg.wm,
        "_wn_",
        cfg.wn);

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.set_compute_pipeline_state(kernel);
    compute_encoder.set_input_array(x, 0);
    compute_encoder.set_input_array(weight0, 1);
    compute_encoder.set_input_array(scales0, 2);
    compute_encoder.set_input_array(biases0, 3);
    compute_encoder.set_input_array(weight1, 4);
    compute_encoder.set_input_array(scales1, 5);
    compute_encoder.set_input_array(biases1, 6);
    compute_encoder.set_input_array(block_meta, 7);
    compute_encoder.set_input_array(block_count, 8);
    compute_encoder.set_output_array(out, 9);
    compute_encoder.set_bytes(max_blocks, 10);
    compute_encoder.set_bytes(M, 11);
    compute_encoder.set_bytes(N, 12);
    compute_encoder.set_bytes(K, 13);

    MTL::Size grid_dims((2 * N + cfg.bn - 1) / cfg.bn, max_blocks, 1);
    MTL::Size group_dims(cfg.wm * cfg.wn * 32, 1, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(DeepseekAffineGatherPairBlocksPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs =
        static_cast<const DeepseekAffineGatherPairBlocksPrimitive&>(other);
    return group_size_ == rhs.group_size_ && bits_ == rhs.bits_ &&
        variant_ == rhs.variant_;
  }
  auto state() const {
    return std::make_tuple(group_size_, bits_, variant_);
  }

 private:
  int group_size_;
  int bits_;
  int variant_;
};

class DeepseekMxfp4GatherExpertPrimitive : public Primitive {
 public:
  explicit DeepseekMxfp4GatherExpertPrimitive(Stream stream, int variant)
      : Primitive(stream), variant_(variant) {
    (void)mxfp4_blocks_variant(variant_);
  }

  static bool unsupported(
      const array& x,
      const array& weight,
      const array& scales,
      const array& indices,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (x.dtype() != float16 && x.dtype() != bfloat16) {
      return true;
    }
    if (weight.dtype() != uint32 || scales.dtype() != uint8 ||
        (indices.dtype() != uint32 && indices.dtype() != int32)) {
      return true;
    }
    if (x.ndim() != 3keys:
        if sk.key and compare_keys(api_key, sk.key):
            return True
    return False


def validate_api_key(api_key: str) -> tuple[bool, str]:
    """Validate API key format requirements.

    Rules:
    - Minimum 4 characters
    - No whitespace characters (space, tab, newline, etc.)
    - Printable characters only (no control characters)
    - ASCII characters only

    The ASCII-only rule is not cosmetic: HTTP request headers are decoded as
    latin-1 by the ASGI layer, so a client cannot transmit a non-ASCII key
    intact. A configured key such as "café" therefore starts the server
    fine but can never be matched over the wire, yielding silent 401s on every
    authenticated request. Rejecting it at configuration time surfaces the
    misconfiguration immediately instead.

    Args:
        api_key: The API key string to validate.

    Returns:
        Tuple of (is_valid, error_message). Error message is empty if valid.
    """
    if len(api_key) < 4:
        return False, "API key must be at least 4 characters"
    if any(c.isspace() for c in api_key):
        return False, "API key must not contain whitespace"
    if not api_key.isprintable():
        return False, "API key must contain only printable characters"
    if not api_key.isascii():
        return False, "API key must contain only ASCII characters"
    return True, ""


def verify_session(request: Request) -> bool:
    """Verify if the request has a valid admin session.

    Checks for a valid session cookie in the request.

    Args:
        request: The FastAPI request object.

    Returns:
        True if the session is valid, False otherwise.
    """
    token = request.cookies.get(SESSION_COOKIE_NAME)
    if not token:
        return False
    return verify_session_token(token)


async def require_admin(request: Request) -> bool:
    """FastAPI dependency to require admin authentication.

    This dependency can be used in route definitions to protect
    admin-only endpoints. It checks for a valid session cookie.

    Args:
        request: The FastAPI request object (injected by FastAPI).

    Returns:
        True if authentication is successful.

    Raises:
        HTTPException: 401 Unauthorized if not authenticated.

    Example:
        >>> from fastapi import Depends
        >>> @app.get("/admin/settings")
        ... async def get_settings(is_admin: bool = Depends(require_admin)):
        ...     return {"settings": "..."}
    """
    # Skip admin auth when skip_api_key_verification is enabled
    if _get_global_settings is not None:
        gs = _get_global_settings()
        if gs is not None and gs.auth.skip_api_key_verification:
            return True

    if not verify_session(request):
        # Browser requests (Accept: text/html) get redirected to login page
        accept = request.headers.get("accept", "")
        if "text/html" in accept:
            raise _RedirectToLogin()
        raise HTTPException(
            status_code=401,
            detail="Admin authentication required",
            headers={"WWW-Authenticate": "Cookie"},
        )
    return True


class _RedirectToLogin(Exception):
    """Raised to trigger a redirect to the admin login page."""
    pass


# ===== FILE: omlx/admin/benchmark.py =====

# SPDX-License-Identifier: Apache-2.0
"""Benchmark execution logic for oMLX admin panel.

Provides single-request and continuous-batching benchmarks with
real-time progress reporting via SSE events.
"""

import asyncio
import json
import logging
import os
import re
import time
import uuid
from dataclasses import dataclass, field
from enum import StrEnum
from functools import lru_cache
from pathlib import Path
from typing import Any, Optional

from pydantic import BaseModel, field_validator

from ..utils.proc_memory import get_lifetime_max_phys_footprint
from ..utils.system_sampler import SystemSampler
from .external_api import ExternalAPIClient, ExternalEndpointConfig

try:
    import mlx.core as mx

    HAS_MLX = True
except ImportError:
    HAS_MLX = False

logger = logging.getLogger(__name__)

# Mng(
                                localized: "appearance.model_scope.all",
                                defaultValue: "All Models",
                                comment: "Models submenu scope option that lists the whole library"
                            )
                        ),
                    ])
                    .frame(width: 200)
                }
            }

            SectionHeader(
                String(
                    localized: "appearance.section.menubar_items",
                    defaultValue: "Menu Bar Items",
                    comment: "Appearance screen section header for the metric item toggles"
                ),
                subtitle: String(
                    localized: "appearance.section.menubar_items.sub",
                    defaultValue: "Each item shows prompt-processing and token-generation speed in the menu bar. Click one for details and a live graph.",
                    comment: "Appearance screen section subtitle explaining the metric items"
                )
            )
            .padding(.top, 18)
            ListGroup {
                Row(
                    label: String(
                        localized: "appearance.row.live_activity",
                        defaultValue: "Live Activity",
                        comment: "Appearance row label for the LIV menubar item toggle"
                    ),
                    sublabel: String(
                        localized: "appearance.row.live_activity.sub",
                        defaultValue: "Current speeds across running requests (LIV).",
                        comment: "Appearance row sublabel for the LIV menubar item toggle"
                    )
                ) {
                    Toggle("", isOn: $showLiveActivity)
                        .labelsHidden()
                        .toggleStyle(.switch)
                }
                Row(
                    label: String(
                        localized: "appearance.row.average_activity",
                        defaultValue: "Average Session Activity",
                        comment: "Appearance row label for the AVG menubar item toggle"
                    ),
                    sublabel: String(
                        localized: "appearance.row.average_activity.sub",
                        defaultValue: "Average speeds since the server started (AVG).",
                        comment: "Appearance row sublabel for the AVG menubar item toggle"
                    )
                ) {
                    Toggle("", isOn: $showAverageActivity)
                        .labelsHidden()
                        .toggleStyle(.switch)
                }
                Row(
                    label: String(
                        localized: "appearance.row.alltime_activity",
                        defaultValue: "All Time Activity",
                        comment: "Appearance row label for the ALL menubar item toggle"
                    ),
                    sublabel: String(
                        localized: "appearance.row.alltime_activity.sub",
                        defaultValue: "Average speeds across all sessions (ALL).",
                        comment: "Appearance row sublabel for the ALL menubar item toggle"
                    )
                ) {
                    Toggle("", isOn: $showAlltimeActivity)
                        .labelsHidden()
                        .toggleStyle(.switch)
                }
                Row(
                    label: String(
                        localized: "appearance.row.cpu_item",
                        defaultValue: "CPU",
                        comment: "Appearance row label for the CPU usage bar menubar item toggle"
                    ),
                    sublabel: String(
                        localized: "appearance.row.cpu_item.sub",
                        defaultValue: "CPU usage as a vertical bar.",
                        comment: "Appearance row sublabel for the CPU usage bar menubar item toggle"
                    )
                ) {
                    s_template? }
                if (!this.selectedModel) return;
                this.profileError = '';
                try {
                    const r = await fetch(
                        `/admin/api/models/${encodeURIComponent(this.selectedModel.id)}/profiles/${encodeURIComponent(name)}`,
                        { method: 'PUT', headers: {'Content-Type':'application/json'},
                          body: JSON.stringify(patch) }
                    );
                    if (r.ok) {
                        const data = await r.json();
                        if (this.activeProfileName === name && patch.new_name) {
                            this.activeProfileName = patch.new_name;
                        }
                        await this.loadProfilesForModel(this.selectedModel.id);
                        if (patch.also_save_as_template) await this.loadTemplates();
                        this.editingProfile = null;
                        return data.profile;
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await r.json().catch(() => ({}));
                        this.profileError = data.detail || 'Failed to update profile';
                    }
                } catch (e) {
                    this.profileError = String(e);
                }
            },
            async createTemplate() {
                this.profileError = '';
                const displayName = this.newTemplate.display_name.trim();
                if (!displayName) {
                    this.profileError = 'Name required';
                    return;
                }
                const autoId = 't-' + Date.now().toString(36) + '-' +
                               Math.random().toString(36).slice(2, 6);
                const body = {
                    name: autoId,
                    display_name: displayName,
                    description: this.newTemplate.description.trim() || null,
                    // Only universal fields — server will filter again defensively.
                    settings: this.formValuesForTemplate(),
                };
                try {
                    const r = await fetch('/admin/api/profile-templates', {
                        method: 'POST',
                        headers: {'Content-Type': 'application/json'},
                        body: JSON.stringify(body),
                    });
                    if (r.ok) {
                        await this.loadTemplates();
                        this.showNewTemplateForm = false;
                        this.newTemplate = { name: '', display_name: '', description: '' };
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await r.json().catch(() => ({}));
                        this.profileError = data.detail || 'Failed to save template';
                    }
                } catch (e) {
                    this.profileError = String(e);
                }
            },
            async updateTemplate(name, patch) {
                this.profileError = '';
                try {
                    const r = await fetch(
                        `/admin/api/profile-templates/${encodeURIComponent(name)}`,
                        { method: 'PUT', headers: {'Content-Type':'application/json'},
                          body: JSON.stringify(patch) }
                    );
                    if (r.ok) {
                        await this.loadTemplates();
                        this.editingTemplate = null;
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await r.json().catch(() => ({}));
                        this.profileError = data.detail || 'Failed to update template';
                    }
                } catch (e) {
                    this.profileError = String(e);
         || x.shape(1) != 1 || weight.ndim() != 3 ||
        scales.ndim() != 3 || indices.ndim() != 1 ||
        indices.size() != x.shape(0)) {
      return true;
    }
    if (!row_contiguous(x) || !row_contiguous(weight) ||
        !row_contiguous(scales) || !row_contiguous(indices)) {
      return true;
    }

    constexpr int bits = 4;
    constexpr int group_size = 32;
    constexpr int values_per_uint32 = 32 / bits;
    const int K = x.shape(2);
    const int E = weight.shape(0);
    const int N = weight.shape(1);
    if (x.shape(0) <= 0 || K <= 0 || N <= 0 || E <= 0) {
      return true;
    }
    if (weight.shape(2) * values_per_uint32 != K || scales.shape(0) != E ||
        scales.shape(1) != N || scales.shape(2) != K / group_size) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error(
        "DeepseekMxfp4GatherExpertPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x = inputs[0];
    const auto& weight = inputs[1];
    const auto& scales = inputs[2];
    const auto& indices = inputs[3];

    out.set_data(allocator::malloc(out.nbytes()));

    const auto cfg = mxfp4_blocks_variant(variant_);
    const int M = x.shape(0);
    const int K = x.shape(2);
    const int E = weight.shape(0);
    const int N = weight.shape(1);

    std::string kname;
    concatenate(
        kname,
        "deepseek_mxfp4_gather_expert_rhs_",
        glm_type_name(x.dtype()),
        "_bm_",
        cfg.bm,
        "_bn_",
        cfg.bn,
        "_bk_",
        cfg.bk,
        "_wm_",
        cfg.wm,
        "_wn_",
        cfg.wn);

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.set_compute_pipeline_state(kernel);
    compute_encoder.set_input_array(x, 0);
    compute_encoder.set_input_array(weight, 1);
    compute_encoder.set_input_array(scales, 2);
    compute_encoder.set_input_array(indices, 3);
    compute_encoder.set_output_array(out, 4);
    compute_encoder.set_bytes(M, 5);
    compute_encoder.set_bytes(N, 6);
    compute_encoder.set_bytes(K, 7);
    compute_encoder.set_bytes(E, 8);

    MTL::Size grid_dims((N + cfg.bn - 1) / cfg.bn, E, 1);
    MTL::Size group_dims(cfg.wm * cfg.wn * 32, 1, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(DeepseekMxfp4GatherExpertPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs =
        static_cast<const DeepseekMxfp4GatherExpertPrimitive&>(other);
    return variant_ == rhs.variant_;
  }
  auto state() const {
    return std::make_tuple(variant_);
  }

 private:
  int variant_;
};

} // namespace

array glm_dsa_q8_vup_flat(
    const array& x,
    const array& weight,
    const array& scales,
    const array& biases,
    StreamOrDevice s /* = {} */) {
  if (x.ndim() != 4 || weight.ndim() != 3 || scales.ndim() != 3 ||
      biases.ndim() != 3) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_q8_vup_flat] expected x rank 4 and "
        << "quantized weights rank 3, got " << x.shape() << ", "
        << weight.shape() << ", " << scales.shape() << ", " << biases.shape()
        << ".";
    throw std::invalid_argument(msg.str());
  }

  const int B = x.shape(0);
  const int H = x.shape(1);
  const int L = x.shape(2);
  constexpr int bits = 8;
  constexpr int group_size = 64;
  constexpr int pack_factor = 32 / bits;
  const int V = weight.shape(1);
  const int K = weight.shape(2) * pack_factor;
  if (H != weight.shape(0) || H != scales.shape(0) ||
      H != biases.shape(0) || V != scales.shape(1) ||
      V != biases.shape(1) || x.shape(3) != K ||
      scales.shape(2) != K / group_size ||
      odule-level storage for active benchmark runs
_benchmark_runs: dict[str, "BenchmarkRun"] = {}

# Valid prompt lengths for single request tests
VALID_PROMPT_LENGTHS = [1024, 4096, 8192, 16384, 32768, 65536, 131072, 200000]

# Valid batch sizes for continuous batching tests
VALID_BATCH_SIZES = [2, 4, 8]


class BenchmarkContextProfile(StrEnum):
    """Stable identifiers for the bundled throughput-benchmark corpora."""

    CODE_PYTHON = "code_python"
    CODE_MIXED = "code_mixed"
    NOVEL_KO = "novel_ko"
    NOVEL_EN = "novel_en"
    NOVEL_JA = "novel_ja"


@dataclass(frozen=True)
class BenchmarkCorpusSpec:
    """Metadata needed to build local and tokenizer-less prompts."""

    filename: str
    label: str
    chars_per_token: float
    start_marker: str | None = None


BENCHMARK_CONTEXT_PROFILES: dict[BenchmarkContextProfile, BenchmarkCorpusSpec] = {
    BenchmarkContextProfile.CODE_PYTHON: BenchmarkCorpusSpec(
        "code_python.txt", "Code (Python)", 4.0
    ),
    BenchmarkContextProfile.CODE_MIXED: BenchmarkCorpusSpec(
        "code_mixed.txt", "Code (Mixed)", 3.5
    ),
    BenchmarkContextProfile.NOVEL_KO: BenchmarkCorpusSpec(
        "novel_ko.txt", "Novel (Korean)", 1.35
    ),
    BenchmarkContextProfile.NOVEL_EN: BenchmarkCorpusSpec(
        "novel_en.txt", "Novel (English)", 4.0, "Call me Ishmael."
    ),
    BenchmarkContextProfile.NOVEL_JA: BenchmarkCorpusSpec(
        "novel_ja.txt", "Novel (Japanese)", 1.6
    ),
}


class BenchmarkRequest(BaseModel):
    """Request model for starting a benchmark."""

    model_id: str
    prompt_lengths: list[int]
    generation_length: int = 128
    batch_sizes: list[int] = []
    context_profile: BenchmarkContextProfile = BenchmarkContextProfile.CODE_PYTHON
    force_lm_engine: bool = False
    # When set, the benchmark runs against a remote OpenAI-compatible
    # endpoint instead of a local engine and model_id is the remote
    # model name (not validated against the local catalog).
    external: Optional[ExternalEndpointConfig] = None

    @field_validator("prompt_lengths")
    @classmethod
    def validate_prompt_lengths(cls, v: list[int]) -> list[int]:
        if not v:
            raise ValueError("At least one prompt length is required")
        for pl in v:
            if pl not in VALID_PROMPT_LENGTHS:
                raise ValueError(
                    f"Invalid prompt length {pl}. Must be one of {VALID_PROMPT_LENGTHS}"
                )
        return sorted(v)

    @field_validator("batch_sizes")
    @classmethod
    def validate_batch_sizes(cls, v: list[int]) -> list[int]:
        for bs in v:
            if bs not in VALID_BATCH_SIZES:
                raise ValueError(
                    f"Invalid batch size {bs}. Must be one of {VALID_BATCH_SIZES}"
                )
        return sorted(v)


@dataclass
class BenchmarkRun:
    """Tracks the state of a running benchmark.

    SSE delivery model: events are appended to `events` (append-only
    log) under `cond`. Subscribers replay `events` from offset 0 then
    wait on `cond` for new entries. `terminal` is set once the final
    event (`upload_done` / `error`) has been published so subscribers
    know to close their stream rather than wait for a follow-up.
    """

    bench_id: str
    request: BenchmarkRequest
    status: str = "running"  # running, completed, cancelled, error
    events: list[dict] = field(default_factory=list)
    cond: asyncio.Condition = field(default_factory=asyncio.Condition)
    terminal: bool = False
    task: Optional[asyncio.Task] = None
    results: list[dict] = field(default_factory=list)
    error_message: str = ""
    # Acceleration features active when the benchmark started. Results are
    # uploaded either way; the flags ride along so the leaderboard can mark
    # and filter them instead of silently mixing them in.
    experimental_features: list[str] = field(default_factory=list)
    # Same snapshot in the upload payload's shape: [{key, label, detail?}].
    feature_flags: list[dict] = field(default_factory=list)
    # Performance-relevant subset of the model'Toggle("", isOn: $showCPUItem)
                        .labelsHidden()
                        .toggleStyle(.switch)
                }
                Row(
                    label: String(
                        localized: "appearance.row.gpu_item",
                        defaultValue: "GPU",
                        comment: "Appearance row label for the GPU usage bar menubar item toggle"
                    ),
                    sublabel: String(
                        localized: "appearance.row.gpu_item.sub",
                        defaultValue: "GPU usage as a vertical bar.",
                        comment: "Appearance row sublabel for the GPU usage bar menubar item toggle"
                    )
                ) {
                    Toggle("", isOn: $showGPUItem)
                        .labelsHidden()
                        .toggleStyle(.switch)
                }
                Row(
                    label: String(
                        localized: "appearance.row.memory_item",
                        defaultValue: "Memory",
                        comment: "Appearance row label for the memory usage bar menubar item toggle"
                    ),
                    sublabel: String(
                        localized: "appearance.row.memory_item.sub",
                        defaultValue: "Memory usage as a vertical bar (MEM).",
                        comment: "Appearance row sublabel for the memory usage bar menubar item toggle"
                    ),
                    isLast: true
                ) {
                    Toggle("", isOn: $showMemoryItem)
                        .labelsHidden()
                        .toggleStyle(.switch)
                }
            }
        }
    }
}

#Preview("AppearanceScreen") {
    ScrollView {
        AppearanceScreen()
            .padding(24)
    }
    .frame(width: 640, height: 520)
    .omlxThemed()
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/ContextBenchScreen.swift =====

// Context Bench screen.
//
// Mirrors the "Context" tab from the HTML admin panel
// (omlx/admin/templates/dashboard/_bench_context.html + dashboard.js
// context bench section). Wires the /api/bench/context/* endpoints onto
// a stack of sections:
//
//   Header          — title + one-line description.
//
//   Configuration   — model picker (Popup over /api/models, loaded
//                     first), target context selector (16k…512k,
//                     default 128k), amber warning callout (long
//                     runtime, unload-all, auto-apply), Run / Cancel.
//
//   Progress        — phase message + percent bar while polling
//                     getContextBenchStatus at 1.5 Hz. The server
//                     mirrors its SSE progress onto the poll endpoint.
//
//   Error banner    — red banner on start failure or a terminal error.
//
//   Result          — applied context window headline + measurement
//                     details, plus the auto-applied / snapshot notes.

import SwiftUI

struct ContextBenchScreen: View {
    @Environment(AppServices.self) private var services
    // VM is owned by AppServices so a running bench survives screen
    // unloads — same pattern as ThroughputBenchScreenVM.
    @Bindable var vm: ContextBenchScreenVM

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            ScreenHeader(
                eyebrow: String(localized: "bench.context.header.eyebrow",
                                defaultValue: "Context Benchmark",
                                comment: "Eyebrow label above the Context Bench screen header"),
                title: String(localized: "bench.context.header.title",
                              defaultValue: "Measure usable context",
                              comment: "Context Bench screen primary header"),
                subtitle: String(localized: "bench.context.header.subtitle",
                                 defaultValue: "Finds the largest context window this machine can actually prefill for a model, then applies it to the model's Context Window setting.",
        }
            },
            async deleteTemplate(name) {
                try {
                    const r = await fetch(
                        `/admin/api/profile-templates/${encodeURIComponent(name)}`,
                        { method: 'DELETE' }
                    );
                    if (r.ok) {
                        await this.loadTemplates();
                    } else if (r.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (e) {
                    console.error('Delete template failed:', e);
                } finally {
                    this.templateDeleteConfirm = null;
                }
            },

            async openModelSettings(model) {
                this.profileError = '';
                this.showNewProfileForm = false;
                this.showNewTemplateForm = false;
                this.editingProfile = null;
                this.editingTemplate = null;
                this.profileDeleteConfirm = null;
                this.templateDeleteConfirm = null;
                const isDiffusion = this.isDiffusionModel(model);
                this.activeProfileName = isDiffusion
                    ? null
                    : ((model.settings && model.settings.active_profile_name) || null);
                if (isDiffusion) {
                    this.profiles = [];
                    this.templates = [];
                    this.profilesDrift = false;
                } else {
                    try {
                        const saved = localStorage.getItem('omlx_profile_scope');
                        if (saved === 'preset' || saved === 'global' || saved === 'model') {
                            this.profileScope = saved;
                        }
                    } catch (e) {}
                    await Promise.all([
                        this.loadProfilesForModel(model.id),
                        this.loadTemplates(),
                    ]);
                    if (this.reasoningParsers.length === 0) {
                        try {
                            const resp = await fetch('/admin/api/grammar/parsers');
                            if (resp.ok) this.reasoningParsers = await resp.json();
                            else if (resp.status === 401) window.location.href = '/admin';
                        } catch (_) { /* network error */ }
                    }
                }
                this.selectedModel = model;
                this.modelSettings = this.buildModelSettingsState(
                    model,
                    model.settings || {},
                );
                if (isDiffusion) {
                    this.profilesDrift = false;
                } else {
                    this.computeDrift();
                }
                this.showModelSettingsModal = true;
            },

            async saveModelSettings() {
                if (!this.selectedModel) return;

                this.savingModelSettings = true;
                try {
                    const response = await fetch(`/admin/api/models/${encodeURIComponent(this.selectedModel.id)}/settings`, {
                        method: 'PUT',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify((() => {
                            const isDiffusion = !!this.modelSettings.is_diffusion_model;
                            // Build chat_template_kwargs and forced_ct_kwargs from ctKwargEntries
                            const chatTemplateKwargs = {};
                            const forcedCtKwargs = [];
                            for (const entry of this.modelSettings.ctKwargEntries) {
                                if (entry.type === 'enable_thinking') {
                                    if (isDiffusion) continue;
                                    chatTemplateKwargs.enable_thinking = entry.value === 'true';
                                    if (entry.force) forcedCtKwargs.push('enable_thinking');
                                } else if (entry.typbiases.shape(2) != K / group_size) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_q8_vup_flat] incompatible shapes: "
        << x.shape() << ", " << weight.shape() << ", " << scales.shape()
        << ", " << biases.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (x.dtype() != float16 && x.dtype() != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_q8_vup_flat] expected float16 or "
        << "bfloat16 input, got " << x.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (weight.dtype() != uint32 || scales.dtype() != x.dtype() ||
      biases.dtype() != x.dtype()) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_q8_vup_flat] expected uint32 weight and "
        << "scale/bias dtype " << x.dtype() << ", got " << weight.dtype()
        << ", " << scales.dtype() << ", " << biases.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  std::vector<array> inputs = {x, weight, scales, biases};
  if (GlmDsaQ8VupFlatPrimitive::unsupported(x, weight, scales, biases, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.glm_dsa_q8_vup_flat] unsupported M3 GLM shape.");
  }

  Shape out_shape{B, L, H * V};
  return array(
      std::move(out_shape),
      x.dtype(),
      std::make_shared<GlmDsaQ8VupFlatPrimitive>(stream),
      std::move(inputs));
}

array glm_moe_weighted_sum(
    const array& x_sorted,
    const array& inv_order,
    const array& scores,
    StreamOrDevice s /* = {} */) {
  if (x_sorted.ndim() != 3 || x_sorted.shape(-2) != 1) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_moe_weighted_sum] expected x_sorted shape "
        << "[N, 1, D], got " << x_sorted.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (scores.ndim() < 2) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_moe_weighted_sum] expected scores rank >= 2, "
        << "got " << scores.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (inv_order.ndim() != 1 || inv_order.dtype() != uint32) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_moe_weighted_sum] expected uint32 inv_order "
        << "rank 1, got " << inv_order.shape() << " dtype "
        << inv_order.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  const int topk = scores.shape(-1);
  const int64_t routed_rows = scores.size();
  const int D = x_sorted.shape(-1);
  if (x_sorted.shape(0) != routed_rows || inv_order.size() != routed_rows) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_moe_weighted_sum] incompatible shapes: "
        << x_sorted.shape() << ", " << inv_order.shape() << ", "
        << scores.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (topk <= 0 || D <= 0) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_moe_weighted_sum] invalid topk or hidden "
        << "dim: topk=" << topk << ", D=" << D << ".";
    throw std::invalid_argument(msg.str());
  }
  if (!issubdtype(x_sorted.dtype(), floating)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_moe_weighted_sum] expected floating "
        << "x_sorted, got " << x_sorted.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  std::vector<array> inputs = {x_sorted, inv_order, scores};
  Shape out_shape = scores.shape();
  out_shape.pop_back();
  out_shape.push_back(D);
  if (GlmMoeWeightedSumPrimitive::unsupported(
          x_sorted, inv_order, scores, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.glm_moe_weighted_sum] unsupported M3 GLM shape.");
  }
  return array(
      std::move(out_shape),
      x_sorted.dtype(),
      std::make_shared<GlmMoeWeightedSumPrimitive>(stream),
      std::move(inputs));
}

array deepseek_mxfp4_gather_qmm_blocks(
    const array& x,
    const array& weight,
    const array& scales,
    const array& block_meta,
    const array& block_count,
    int variant,
    StreamOrDevice s /* = {} */) {
  (void)mxfs settings at run start.
    model_settings_snapshot: Optional[dict] = None
    # Host telemetry sampler, running for the duration of the tests.
    sampler: Optional[Any] = None
    # Lifetime footprint high-water mark before the tests began, so the run's
    # own peak can be told apart from a larger one set earlier in the process.
    lifetime_footprint_at_start: int = 0
    # Mirror of the upload SSE events so REST consumers (e.g. native Swift
    # app polling /results) can render leaderboard status without opening
    # the stream. Phases: "idle" → "uploading" → "done" | "skipped". The
    # browser HTML still consumes the SSE stream directly; this is purely
    # additive state that lives alongside it.
    upload_state: dict = field(
        default_factory=lambda: {
            "phase": "idle",
            "results": [],  # per-context-length: {context_length, id?, url?, duplicate?, error?}
            "total": 0,
            "success_count": 0,
            "failed_count": 0,
            "owner_hash": None,  # display hash, populated on upload_done
            "skipped_reason": None,  # only "external_endpoint" reaches this now
            # Always empty. Kept because BenchDTO.swift declares it non-optional,
            # so dropping the key would fail decoding on every app build that has
            # not been updated — which turns into a per-second error loop while the
            # results poller runs.
            "skipped_features": [],
            "feature_flags": [],  # [{key, label, detail?}]
        }
    )


# Event types that close the SSE stream for a bench run. `done` is NOT
# terminal — it marks "tests finished, upload starting"; the real end of
# stream is `upload_done` (or `error`). `upload_skipped` is the external
# endpoint's last event: without it here, subscribers to an external run would
# wait for an `upload_done` that never comes.
_BENCH_TERMINAL_TYPES = frozenset({"upload_done", "upload_skipped", "error"})


@dataclass(frozen=True)
class _FeatureFlagSpec:
    """One acceleration toggle, in both the legacy and upload projections."""

    attr: str
    legacy: str
    key: str
    label: str
    detail_attr: Optional[str] = None
    detail_key_fmt: Optional[str] = None
    detail_label_fmt: Optional[str] = None


# `mtp_enabled` is surfaced as "Lightning MTP" everywhere in the UI, so the
# upload key follows the user-facing name rather than the settings field.
_FEATURE_FLAG_SPECS = (
    _FeatureFlagSpec("dflash_enabled", "dflash", "dflash", "DFlash"),
    _FeatureFlagSpec(
        "specprefill_enabled", "specprefill", "specprefill", "SpecPrefill"
    ),
    _FeatureFlagSpec(
        "turboquant_kv_enabled",
        "turboquant",
        "turboquant_kv",
        "TurboQuant KV",
        detail_attr="turboquant_kv_bits",
        detail_key_fmt="_{}bit",
        detail_label_fmt=" {}-bit",
    ),
    _FeatureFlagSpec("mtp_enabled", "mtp", "lightning_mtp", "Lightning MTP"),
    _FeatureFlagSpec("vlm_mtp_enabled", "vlm_mtp", "vlm_mtp", "VLM MTP"),
)


def _sample_window(run: "BenchmarkRun", window_start: float) -> Optional[dict]:
    """Aggregate host telemetry for the interval a single test occupied."""
    if run.sampler is None:
        return None
    try:
        return run.sampler.window(window_start, time.monotonic())
    except Exception as e:  # noqa: BLE001
        logger.debug(f"Benchmark: system metrics unavailable: {e}")
        return None


def _detect_experimental_features(model_settings: Any) -> list[str]:
    """Return benchmark-skewing model features enabled in settings."""
    return [
        spec.legacy
        for spec in _FEATURE_FLAG_SPECS
        if getattr(model_settings, spec.attr, False)
    ]


def _format_bits(value: Any) -> Optional[str]:
    """Render a bit-width for display, dropping a trailing .0 (4.0 -> "4")."""
    try:
        number = float(value)
    except (TypeError, ValueError):
        return None
    return f"{number:g}"


def _derive_feature_flags(model_settings: Any) -> list[dict]:
    """Build the upload projection of the active acceleration feature                                 comment: "Context Bench screen subtitle describing what the benchmark measures")
            )

            ConfigurationSection(
                models: vm.models,
                selectedModelId: $vm.selectedModelId,
                targetTokens: $vm.targetTokens,
                targetOptions: vm.availableTargetOptions,
                prefillPriority: vm.prefillPriority,
                running: vm.running,
                canRun: vm.canRun,
                onRun: { vm.runBenchmark(client: services.client) },
                onCancel: { vm.cancelBenchmark(client: services.client) },
                onPriorityChange: { vm.setPrefillPriority($0, client: services.client) }
            )

            if vm.running {
                ProgressCard(
                    message: vm.message,
                    progress: vm.progress
                )
            }

            MessageBanner(error: vm.lastError)

            if let result = vm.result {
                ResultSection(result: result)
            }
        }
        // `start()` is idempotent: it refreshes the model list but leaves
        // the running-bench state alone, so navigation doesn't lose an
        // in-flight measurement.
        .task { await vm.start(client: services.client) }
        // Picking a model with a smaller native context hides the larger
        // target presets — snap the selection back into range.
        .onChange(of: vm.selectedModelId) { _, _ in
            vm.clampTargetToModel()
        }
    }
}

// MARK: - Configuration

private struct ConfigurationSection: View {
    let models: [ModelDTO]
    @Binding var selectedModelId: String
    @Binding var targetTokens: Int
    let targetOptions: [Int]
    let prefillPriority: String
    let running: Bool
    let canRun: Bool
    let onRun: () -> Void
    let onCancel: () -> Void
    let onPriorityChange: (String) -> Void

    var body: some View {
        SectionHeader(
            String(localized: "bench.context.section.configuration",
                   defaultValue: "Configuration",
                   comment: "Section header for the Context Bench configuration block"),
            subtitle: models.isEmpty
                ? String(localized: "bench.context.subtitle.loading_models",
                         defaultValue: "Loading models…",
                         comment: "Context Bench section subtitle while models are loading")
                : String(localized: "bench.context.subtitle.model_count",
                         defaultValue: "Models available: \(models.count)",
                         comment: "Context Bench section subtitle showing how many models are available; placeholder is the count")
        )

        ListGroup {
            Row(label: String(localized: "bench.context.row.model.label",
                              defaultValue: "Model",
                              comment: "Row label for the Context Bench model picker"),
                sublabel: String(localized: "bench.context.row.model.sub",
                                 defaultValue: "Loaded or unloaded — server will load on demand",
                                 comment: "Sublabel under the Context Bench model picker")) {
                Popup(
                    selection: $selectedModelId,
                    width: 320,
                    options: modelOptions
                )
            }

            Row(label: String(localized: "bench.context.row.target.label",
                              defaultValue: "Maximum context to test",
                              comment: "Row label for the Context Bench target selector"),
                sublabel: String(localized: "bench.context.row.target.sub",
                                 defaultValue: "The search stops at this size; larger targets take longer to verify",
                                 comment: "Sublabel under the Context Bench target selector")) {
                Segmented(
                    selection: $targetTokens,
                    options: targetOptions.map {
                        (vae === 'reasoning_effort') {
                                    if (isDiffusion) continue;
                                    chatTemplateKwargs.reasoning_effort = entry.value;
                                    if (entry.force) forcedCtKwargs.push('reasoning_effort');
                                } else if (entry.type === 'custom' && entry.key && entry.key.trim()) {
                                    let val = entry.value;
                                    if (val === 'true') val = true;
                                    else if (val === 'false') val = false;
                                    else if (!isNaN(Number(val)) && val.trim() !== '') val = Number(val);
                                    const key = entry.key.trim();
                                    if (isDiffusion && this.isDiffusionUnsupportedCtKwarg(key)) {
                                        continue;
                                    }
                                    chatTemplateKwargs[key] = val;
                                    if (entry.force) forcedCtKwargs.push(key);
                                }
                            }
                            const payload = {
                                model_alias: this.modelSettings.model_alias?.trim() || null,
                                model_type_override: this.modelSettings.model_type_override || null,
                                max_context_window: this.modelSettings.max_context_window || null,
                                max_tokens: this.modelSettings.max_tokens || null,
                                temperature: Number.isFinite(this.modelSettings.temperature) ? this.modelSettings.temperature : null,
                                top_p: Number.isFinite(this.modelSettings.top_p) ? this.modelSettings.top_p : null,
                                top_k: Number.isFinite(this.modelSettings.top_k) ? this.modelSettings.top_k : null,
                                repetition_penalty: Number.isFinite(this.modelSettings.repetition_penalty) ? this.modelSettings.repetition_penalty : null,
                                min_p: Number.isFinite(this.modelSettings.min_p) ? this.modelSettings.min_p : null,
                                presence_penalty: Number.isFinite(this.modelSettings.presence_penalty) ? this.modelSettings.presence_penalty : null,
                                force_sampling: this.modelSettings.force_sampling,
                                reasoning_parser: this.modelSettings.reasoning_parser || null,
                                ttl_seconds: this.modelSettings.ttl_seconds || null,
                                index_cache_freq: this.modelSettings.enableIndexCache
                                    ? (this.modelSettings.index_cache_freq || 4)
                                    : 0,
                                enable_thinking: this.modelSettings.enable_thinking,
                                thinking_budget_enabled: this.modelSettings.enableThinkingBudget,
                                thinking_budget_tokens: this.modelSettings.enableThinkingBudget
                                    ? (this.modelSettings.thinking_budget_tokens || null)
                                    : 0,
                                guided_grammar_enabled: this.modelSettings.guided_grammar_enabled,
                                guided_grammar: this.modelSettings.guided_grammar_enabled
                                    ? (this.modelSettings.guided_grammar || null)
                                    : null,
                                max_tool_result_tokens: this.modelSettings.enableToolResultLimit
                                    ? (this.modelSettings.max_tool_result_tokens || null)
                                    : 0,
                                chat_template_kwargs: Object.keys(chatTemplateKwargs).length > 0
                                    ? chatTemplateKwargs : null,
                                forced_ct_kwargs: forcedCtKwargs.length > 0
                                    ? forcedCtKwargs : null,
                    p4_blocks_variant(variant);

  if (x.ndim() != 3 || x.shape(1) != 1 || weight.ndim() != 3 ||
      scales.ndim() != 3 || block_meta.ndim() != 2 ||
      block_meta.shape(1) != 3 || block_count.size() != 1) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_blocks] expected "
        << "x [M,1,K], weight [E,N,K/8], scales [E,N,K/32], "
        << "block_meta [B,3], block_count [1], got " << x.shape() << ", "
        << weight.shape() << ", " << scales.shape() << ", "
        << block_meta.shape() << ", " << block_count.shape() << ".";
    throw std::invalid_argument(msg.str());
  }

  constexpr int bits = 4;
  constexpr int group_size = 32;
  constexpr int values_per_uint32 = 32 / bits;
  const int K = x.shape(2);
  const int E = weight.shape(0);
  const int N = weight.shape(1);
  if (weight.shape(2) * values_per_uint32 != K || scales.shape(0) != E ||
      scales.shape(1) != N || scales.shape(2) != K / group_size) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_blocks] "
        << "incompatible shapes: " << x.shape() << ", " << weight.shape()
        << ", " << scales.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (x.dtype() != float16 && x.dtype() != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_blocks] expected "
        << "float16 or bfloat16 input, got " << x.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (weight.dtype() != uint32 || scales.dtype() != uint8 ||
      block_meta.dtype() != int32 || block_count.dtype() != int32) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_blocks] expected "
        << "uint32 weight, uint8 scales, int32 block_meta/count, got "
        << weight.dtype() << ", " << scales.dtype() << ", "
        << block_meta.dtype() << ", " << block_count.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  std::vector<array> inputs = {x, weight, scales, block_meta, block_count};
  if (DeepseekMxfp4GatherBlocksPrimitive::unsupported(
          x, weight, scales, block_meta, block_count, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_blocks] unsupported shape.");
  }

  Shape out_shape{x.shape(0), 1, N};
  return array(
      std::move(out_shape),
      x.dtype(),
      std::make_shared<DeepseekMxfp4GatherBlocksPrimitive>(stream, variant),
      std::move(inputs));
}

array deepseek_mxfp4_gather_qmm_pair_blocks(
    const array& x,
    const array& weight0,
    const array& scales0,
    const array& weight1,
    const array& scales1,
    const array& block_meta,
    const array& block_count,
    int variant,
    StreamOrDevice s /* = {} */) {
  (void)mxfp4_blocks_variant(variant);

  if (x.ndim() != 3 || x.shape(1) != 1 || weight0.ndim() != 3 ||
      scales0.ndim() != 3 || weight1.ndim() != 3 || scales1.ndim() != 3 ||
      block_meta.ndim() != 2 || block_meta.shape(1) != 3 ||
      block_count.size() != 1) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_pair_blocks] "
        << "expected x [M,1,K], two weights [E,N,K/8], two scales "
        << "[E,N,K/32], block_meta [B,3], block_count [1], got "
        << x.shape() << ", " << weight0.shape() << ", " << scales0.shape()
        << ", " << weight1.shape() << ", " << scales1.shape() << ", "
        << block_meta.shape() << ", " << block_count.shape() << ".";
    throw std::invalid_argument(msg.str());
  }

  constexpr int bits = 4;
  constexpr int group_size = 32;
  constexpr int values_per_uint32 = 32 / bits;
  const int K = x.shape(2);
  const int E = weight0.shape(0);
  const int N = weight0.shape(1);
  if (weight1.shape() != weight0.shape() || scales1.shape() != scales0.shape() ||
      weight0.shape(2) * values_per_uint32 != K || scales0.shape(0) != E ||
      scales0.shape(1) != N || scales0.shape(2) != K / group_size) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_pair_bs.

    Objects rather than bare keys: the app and omlx.ai ship independently, so
    carrying the display label means a newly added feature renders correctly on
    the site from day one instead of showing a raw snake_case key until the
    next site deploy. Only active features are included — the site derives
    "this run was accelerated" from the list being non-empty.
    """
    flags: list[dict] = []
    for spec in _FEATURE_FLAG_SPECS:
        if not getattr(model_settings, spec.attr, False):
            continue
        key, label = spec.key, spec.label
        if spec.detail_attr:
            bits = _format_bits(getattr(model_settings, spec.detail_attr, None))
            if bits:
                # Keys must stay [a-z0-9_], so 2.5 becomes 2_5.
                key += spec.detail_key_fmt.format(bits.replace(".", "_"))
                label += spec.detail_label_fmt.format(bits)
        flags.append({"key": key, "label": label})
    return flags


# Performance-relevant settings only, as an allowlist rather than a denylist:
# ModelSettings gains fields regularly, and a denylist would ship every future
# addition to a public endpoint by default.
#
# Excluded on purpose: display_name / description / model_alias (user-authored
# free text), is_pinned / is_default / is_hidden / is_favorite /
# active_profile_name / ttl_seconds (local organization), the guided_grammar
# body (unbounded; the boolean is kept), chat_template_kwargs and
# forced_ct_kwargs (arbitrary user dicts), and trust_remote_code (security
# posture, not performance). The *_draft_model fields are included but reduced
# to a basename — the drafter's identity explains an MTP/DFlash result, while
# the full path would leak the local filesystem layout and the OS username.
_UPLOADED_SETTING_FIELDS = (
    "max_context_window",
    "max_tokens",
    "temperature",
    "top_p",
    "top_k",
    "min_p",
    "repetition_penalty",
    "presence_penalty",
    "force_sampling",
    "enable_thinking",
    "thinking_budget_enabled",
    "thinking_budget_tokens",
    "reasoning_parser",
    "guided_grammar_enabled",
    "model_type_override",
    "index_cache_freq",
    "turboquant_kv_enabled",
    "turboquant_kv_bits",
    "turboquant_skip_last",
    "specprefill_enabled",
    "specprefill_draft_model",
    "specprefill_keep_pct",
    "specprefill_threshold",
    "dflash_enabled",
    "dflash_draft_model",
    "dflash_draft_quant_enabled",
    "dflash_draft_quant_weight_bits",
    "dflash_draft_quant_activation_bits",
    "dflash_draft_quant_group_size",
    "dflash_max_ctx",
    "dflash_in_memory_cache",
    "dflash_in_memory_cache_max_entries",
    "dflash_ssd_cache",
    "dflash_draft_window_size",
    "dflash_draft_sink_size",
    "dflash_verify_mode",
    "mtp_enabled",
    "mtp_num_draft_tokens",
    "vlm_mtp_enabled",
    "vlm_mtp_draft_model",
    "vlm_mtp_draft_block_size",
)

_PATH_VALUED_SETTING_FIELDS = frozenset(
    {
        "specprefill_draft_model",
        "dflash_draft_model",
        "vlm_mtp_draft_model",
    }
)

_MAX_UPLOADED_SETTINGS_BYTES = 4096


def _filter_uploaded_settings(model_settings: Any) -> Optional[dict]:
    """Project model settings onto the uploadable allowlist."""
    to_dict = getattr(model_settings, "to_dict", None)
    if not callable(to_dict):
        return None
    try:
        raw = to_dict()
    except Exception as e:  # noqa: BLE001
        logger.warning(f"Benchmark: failed to serialize model settings: {e}")
        return None

    filtered: dict = {}
    for key in _UPLOADED_SETTING_FIELDS:
        if key not in raw:
            continue
        value = raw[key]
        if key in _PATH_VALUED_SETTING_FIELDS and isinstance(value, str):
            value = os.path.basename(value.rstrip("/")) or value
        filtered[key] = value

    if len(json.dumps(filtered, separators=(",", ":"))) > _MAX_UPLOADED_SETTINGS_BYTES:
        logger.warning(
            "Benchmark: model settings snapshot exceeded "
            f"{_MAX_UPLOADED_SETTINGS_BYTES} bytes, uploading accelerator flags only"
        )
        filtered = {
    lue: $0, label: "\($0 / 1024)k")
                    }
                )
                .frame(width: 320)
                .disabled(running)
            }

            Row(label: String(localized: "bench.context.row.priority.label",
                              defaultValue: "Prefill Priority",
                              comment: "Row label for the prefill priority segmented control on the Context Bench screen"),
                sublabel: String(localized: "bench.context.row.priority.sub",
                                 defaultValue: "Mirrors the global setting and saves immediately — serving uses the same mode, so the measured value stays valid",
                                 comment: "Sublabel explaining the Context Bench prefill priority control mirrors the global setting")) {
                Segmented(
                    selection: Binding(
                        get: { prefillPriority },
                        set: { onPriorityChange($0) }
                    ),
                    options: [
                        (value: "context",
                         label: String(localized: "prefill_priority.option.max_context",
                                       defaultValue: "Max Context",
                                       comment: "Prefill priority option that favors the largest context")),
                        (value: "speed",
                         label: String(localized: "prefill_priority.option.speed",
                                       defaultValue: "Speed",
                                       comment: "Prefill priority option that favors prefill speed")),
                    ],
                    icons: ["arrow.up.left.and.arrow.down.right", "speedometer"]
                )
                .frame(width: 240)
                .disabled(running)
            }

            FreeRow {
                WarningCallout()
            }

            Row(isLast: true) {
                HStack {
                    Spacer()
                    if running {
                        Button {
                            onCancel()
                        } label: {
                            Label(String(localized: "common.cancel",
                                         defaultValue: "Cancel",
                                         comment: "Generic Cancel button label"),
                                  systemImage: "stop.fill")
                                .labelStyle(.titleAndIcon)
                        }
                        .buttonStyle(.omlx(.destructive))
                    } else {
                        Button {
                            onRun()
                        } label: {
                            Label(String(localized: "bench.context.button.run",
                                         defaultValue: "Start Benchmark",
                                         comment: "Context Bench primary button that starts the measurement"),
                                  systemImage: "play.fill")
                                .labelStyle(.titleAndIcon)
                        }
                        .buttonStyle(.omlx(.primary))
                        .disabled(!canRun)
                    }
                }
            }
        }
    }

    private var modelOptions: [PopupOption<String>] {
        var opts = [PopupOption(value: "", label: String(localized: "bench.context.model.placeholder",
                                                         defaultValue: "Select a model…",
                                                         comment: "Placeholder option in the Context Bench model picker"))]
        opts += models.map { m in
            PopupOption(
                value: m.id,
                label: m.loaded
                    ? String(localized: "bench.context.model.loaded_badge",
                             defaultValue: "\(m.id) • loaded",
                             comment: "Model picker entry for a loaded model; placeholder is the model id")
                    : m.id
            )
        }
        return opts
    }
}

// MARK: - Warning c            turboquant_kv_enabled: this.modelSettings.turboquant_kv_enabled,
                                turboquant_kv_bits: this.modelSettings.turboquant_kv_enabled
                                    ? (parseFloat(this.modelSettings.turboquant_kv_bits) || 4)
                                    : 4,
                                specprefill_enabled: this.modelSettings.specprefill_enabled,
                                specprefill_draft_model: this.modelSettings.specprefill_draft_model || null,
                                specprefill_keep_pct: this.modelSettings.specprefill_enabled
                                    ? parseFloat(this.modelSettings.specprefill_keep_pct) || 0.2
                                    : null,
                                specprefill_threshold: this.modelSettings.specprefill_enabled
                                    ? (this.modelSettings.specprefill_threshold || null)
                                    : null,
                                dflash_enabled: this.modelSettings.dflash_enabled,
                                dflash_draft_model: this.modelSettings.dflash_draft_model || null,
                                dflash_draft_quant_enabled: this.modelSettings.dflash_enabled && !!this.modelSettings.dflash_draft_quant_enabled,
                                dflash_draft_quant_weight_bits: this.modelSettings.dflash_enabled && this.modelSettings.dflash_draft_quant_enabled
                                    ? parseInt(this.modelSettings.dflash_draft_quant_weight_bits)
                                    : null,
                                dflash_draft_quant_activation_bits: this.modelSettings.dflash_enabled && this.modelSettings.dflash_draft_quant_enabled
                                    ? parseInt(this.modelSettings.dflash_draft_quant_activation_bits)
                                    : null,
                                dflash_draft_quant_group_size: this.modelSettings.dflash_enabled && this.modelSettings.dflash_draft_quant_enabled
                                    ? parseInt(this.modelSettings.dflash_draft_quant_group_size)
                                    : null,
                                dflash_max_ctx: this.modelSettings.dflash_enabled && this.modelSettings.dflash_max_ctx
                                    ? parseInt(this.modelSettings.dflash_max_ctx)
                                    : null,
                                dflash_in_memory_cache: this.modelSettings.dflash_enabled
                                    ? !!this.modelSettings.dflash_in_memory_cache
                                    : true,
                                dflash_in_memory_cache_max_entries: this.modelSettings.dflash_enabled
                                    ? (parseInt(this.modelSettings.dflash_in_memory_cache_max_entries) || 4)
                                    : 4,
                                dflash_in_memory_cache_max_bytes: this.modelSettings.dflash_enabled
                                    ? Math.max(1, parseInt(this.modelSettings.dflash_in_memory_cache_max_gib) || 8) * (1024 ** 3)
                                    : 8 * (1024 ** 3),
                                dflash_ssd_cache: this.modelSettings.dflash_enabled
                                    && !!this.modelSettings.dflash_in_memory_cache
                                    && !!this.modelSettings.dflash_ssd_cache_available
                                    && !!this.modelSettings.dflash_ssd_cache,
                                dflash_ssd_cache_max_bytes: this.modelSettings.dflash_enabled
                                    ? Math.max(1, parseInt(this.modelSettings.dflash_ssd_cache_max_gib) || 20) * (1024 ** 3)
                                    : 20 * (1024 ** 3),
                                // Long-context tuning. Null → server keeps it null → dflash-mlx default.
                                dflash_draft_window_size: this.modelSettings.dflash_enabled
                                    && this.modelSettings.dflash_draft_window_size
                                    ? palocks] "
        << "incompatible shapes: " << x.shape() << ", " << weight0.shape()
        << ", " << scales0.shape() << ", " << weight1.shape() << ", "
        << scales1.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (x.dtype() != float16 && x.dtype() != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_pair_blocks] expected "
        << "float16 or bfloat16 input, got " << x.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (weight0.dtype() != uint32 || scales0.dtype() != uint8 ||
      weight1.dtype() != uint32 || scales1.dtype() != uint8 ||
      block_meta.dtype() != int32 || block_count.dtype() != int32) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_pair_blocks] expected "
        << "uint32 weights, uint8 scales, int32 block_meta/count, got "
        << weight0.dtype() << ", " << scales0.dtype() << ", "
        << weight1.dtype() << ", " << scales1.dtype() << ", "
        << block_meta.dtype() << ", " << block_count.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  std::vector<array> inputs = {
      x, weight0, scales0, weight1, scales1, block_meta, block_count};
  if (DeepseekMxfp4GatherPairBlocksPrimitive::unsupported(
          x, weight0, scales0, weight1, scales1, block_meta, block_count, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_pair_blocks] unsupported shape.");
  }

  Shape out_shape{2, x.shape(0), 1, N};
  return array(
      std::move(out_shape),
      x.dtype(),
      std::make_shared<DeepseekMxfp4GatherPairBlocksPrimitive>(stream, variant),
      std::move(inputs));
}

array deepseek_mxfp4_gather_qmm_pair_concat_blocks(
    const array& x,
    const array& weight0,
    const array& scales0,
    const array& weight1,
    const array& scales1,
    const array& block_meta,
    const array& block_count,
    int variant,
    StreamOrDevice s /* = {} */) {
  const auto cfg = mxfp4_blocks_variant(variant);
  auto stream = to_stream(s);
  if (DeepseekMxfp4GatherPairBlocksPrimitive::unsupported(
          x, weight0, scales0, weight1, scales1, block_meta, block_count, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_pair_concat_blocks] unsupported shape.");
  }
  const int N = weight0.shape(1);
  if (N % cfg.bn != 0) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_pair_concat_blocks] "
        "output dimension must be divisible by the block N.");
  }
  std::vector<array> inputs = {
      x, weight0, scales0, weight1, scales1, block_meta, block_count};
  Shape out_shape{x.shape(0), 1, 2 * N};
  return array(
      std::move(out_shape),
      x.dtype(),
      std::make_shared<DeepseekMxfp4GatherPairBlocksPrimitive>(
          stream, variant, true),
      std::move(inputs));
}

array deepseek_affine_gather_qmm_blocks(
    const array& x,
    const array& weight,
    const array& scales,
    const array& biases,
    const array& block_meta,
    const array& block_count,
    int group_size,
    int bits,
    int variant,
    StreamOrDevice s /* = {} */) {
  (void)mxfp4_blocks_variant(variant);

  if (x.ndim() != 3 || x.shape(1) != 1 || weight.ndim() != 3 ||
      scales.ndim() != 3 || biases.ndim() != 3 || block_meta.ndim() != 2 ||
      block_meta.shape(1) != 3 || block_count.size() != 1) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_affine_gather_qmm_blocks] expected "
        << "x [M,1,K], weight [E,N,packed_words], scales/biases "
        << "[E,N,K/group_size], block_meta [B,3], block_count [1], got "
        << x.shape() << ", " << weight.shape() << ", " << scales.shape()
        << ", " << biases.shape() << ", " << block_meta.shape() << ", "
        << block_count.shape() << ".";
    throw std::invalid_argument(msg.str());
  }

  if (!supported_deepseek_affine(group_size, bits)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_affine_gather_qmm_block        spec.attr: filtered[spec.attr]
            for spec in _FEATURE_FLAG_SPECS
            if spec.attr in filtered
        }
    return filtered


def _with_benchmark_context(
    context_profile: BenchmarkContextProfile | str,
    model_settings: dict | None,
) -> dict:
    """Prepend the benchmark context to the uploaded settings snapshot."""
    settings = dict(model_settings or {})
    settings.pop("benchmark_context", None)
    return {
        "benchmark_context": benchmark_context_label(context_profile),
        **settings,
    }


def get_run(bench_id: str) -> Optional[BenchmarkRun]:
    """Get a benchmark run by ID."""
    return _benchmark_runs.get(bench_id)


def get_active_run() -> Optional[BenchmarkRun]:
    """Return the currently-running throughput benchmark, if any.

    Discovery surface for clients that need to attach to an in-progress
    run without knowing the bench_id upfront (page refresh, second tab).
    Returns the first run with status == "running"; throughput benches
    are 1-at-a-time so there's never more than one.
    """
    for run in _benchmark_runs.values():
        if run.status == "running":
            return run
    return None


def create_run(request: BenchmarkRequest) -> BenchmarkRun:
    """Create and register a new benchmark run."""
    bench_id = f"bench-{uuid.uuid4().hex[:12]}"
    run = BenchmarkRun(bench_id=bench_id, request=request)
    _benchmark_runs[bench_id] = run
    return run


def cleanup_old_runs(max_runs: int = 10) -> None:
    """Remove old completed runs to prevent memory leaks."""
    completed = [
        (bid, r)
        for bid, r in _benchmark_runs.items()
        if r.status in ("completed", "cancelled", "error")
    ]
    if len(completed) > max_runs:
        for bid, _ in completed[:-max_runs]:
            del _benchmark_runs[bid]


# Bundled corpora for benchmark prompts. They contain long-form code or prose,
# never a short filler sentence. A whole corpus may repeat for a tokenizer that
# compresses it unusually well, but the repeated unit is hundreds of thousands
# of natural tokens rather than a predictable one-line loop.
_BENCH_CORPUS_DIR = Path(__file__).parent / "bench_corpora"
_PROMPT_BUILD_MAX_ATTEMPTS = 16


def benchmark_context_label(profile: BenchmarkContextProfile | str) -> str:
    """Return the user-facing label for a benchmark context profile."""
    normalized = BenchmarkContextProfile(profile)
    return BENCHMARK_CONTEXT_PROFILES[normalized].label


@lru_cache(maxsize=len(BENCHMARK_CONTEXT_PROFILES))
def _load_bench_corpus(
    context_profile: (
        BenchmarkContextProfile | str
    ) = BenchmarkContextProfile.CODE_PYTHON,
) -> str:
    profile = BenchmarkContextProfile(context_profile)
    spec = BENCHMARK_CONTEXT_PROFILES[profile]
    path = _BENCH_CORPUS_DIR / spec.filename
    corpus = path.read_text(encoding="utf-8")
    if spec.start_marker:
        start = corpus.find(spec.start_marker)
        if start < 0:
            raise RuntimeError(
                f"Benchmark corpus at {path} is missing the content start marker"
            )
        corpus = corpus[start:]
    if not corpus:
        raise RuntimeError(f"Benchmark corpus at {path} is empty")
    return corpus


def _generate_prompt(
    tokenizer: Any,
    target_tokens: int,
    context_profile: (
        BenchmarkContextProfile | str
    ) = BenchmarkContextProfile.CODE_PYTHON,
) -> list[int]:
    """Generate exactly ``target_tokens`` benchmark-corpus token IDs.

    Uses a unique UUID prefix to prevent SSD cache hits from previous sessions.
    The prefix and corpus are encoded together so tokenizer boundary merges and
    special-token insertion happen exactly once. The token IDs are passed to the
    engine directly; decoding them back to text would make exact length depend
    on tokenizer round-trip behavior.
    """
    if target_tokens <= 0:
        raise ValueError("target_tokens must be positive")

    unique_prefix = f"BENCH-{uuid.uuid4().hex} "
    profile = BenchmarkContextProfile(context_profile)
    spec = BENCHMARK_CONTEXT_PROFILES[profile]
allout

private struct WarningCallout: View {
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        HStack(alignment: .top, spacing: 8) {
            Image(systemName: "exclamationmark.triangle")
                .foregroundStyle(theme.amberDot)
                .font(.system(size: 11))
                .padding(.top, 1)
            VStack(alignment: .leading, spacing: 4) {
                Text(String(localized: "bench.context.warning.title",
                            defaultValue: "Before you start",
                            comment: "Heading of the warning callout above the Context Bench start button"))
                    .font(.omlxText(12, weight: .semibold))
                    .foregroundStyle(theme.text)
                Text(String(localized: "bench.context.warning.body",
                            defaultValue: "This benchmark can take a long time — verification prefills a real prompt at the measured size, which may take many minutes for large models. All loaded models are unloaded when it starts, interrupting active requests. When it finishes, the result is automatically applied to the model's Context Window setting.",
                            comment: "Body of the warning callout above the Context Bench start button"))
                    .font(.omlxText(11))
                    .foregroundStyle(theme.textSecondary)
                    .fixedSize(horizontal: false, vertical: true)
            }
            Spacer(minLength: 0)
        }
        .padding(10)
        .background(theme.amberDot.opacity(0.10))
        .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
    }
}

// MARK: - Progress

private struct ProgressCard: View {
    let message: String
    let progress: Double

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        ListGroup {
            FreeRow(isLast: true) {
                VStack(alignment: .leading, spacing: 8) {
                    HStack(spacing: 10) {
                        ProgressView()
                            .controlSize(.small)
                        Text(message.isEmpty
                             ? String(localized: "bench.context.progress.starting",
                                      defaultValue: "Starting…",
                                      comment: "Context Bench progress label before the first server update arrives")
                             : message)
                            .font(.omlxText(12))
                            .foregroundStyle(theme.textSecondary)
                            .lineLimit(2)
                        Spacer(minLength: 0)
                        Text("\(Int(progress.rounded()))%")
                            .font(.omlxText(12, weight: .medium))
                            .foregroundStyle(theme.text)
                            .monospacedDigit()
                    }
                    ProgressBar(progress: max(0, min(progress / 100, 1)))
                }
            }
        }
    }
}

// MARK: - Result

private struct ResultSection: View {
    let result: ContextBenchResultDTO

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        SectionHeader(
            String(localized: "bench.context.section.result",
                   defaultValue: "Result",
                   comment: "Section header for the Context Bench result block"),
            subtitle: result.modelId
        )

        ListGroup {
            FreeRow {
                HStack(alignment: .firstTextBaseline, spacing: 6) {
                    Text(result.appliedTokens.formatted())
                        .font(.omlxText(26, weight: .bold))
                        .foregroundStyle(theme.text)
                        .monospacedDigit()
                    Text(String(localized: "bench.context.result.tokens_label",
                                defaultValue: "tokens applied to Context Window",
                                comment: "Unit caption next to the applied context window headline number"))
                        .font(.omlxText(12))
         rseInt(this.modelSettings.dflash_draft_window_size)
                                    : null,
                                dflash_draft_sink_size: this.modelSettings.dflash_enabled
                                    && this.modelSettings.dflash_draft_sink_size !== null
                                    && this.modelSettings.dflash_draft_sink_size !== undefined
                                    && this.modelSettings.dflash_draft_sink_size !== ''
                                    ? parseInt(this.modelSettings.dflash_draft_sink_size)
                                    : null,
                                dflash_verify_mode: this.modelSettings.dflash_enabled
                                    ? (this.modelSettings.dflash_verify_mode || 'adaptive')
                                    : null,
                                mtp_enabled: !!this.modelSettings.mtp_enabled,
                                vlm_mtp_enabled: !!this.modelSettings.vlm_mtp_enabled,
                                vlm_mtp_draft_model: this.modelSettings.vlm_mtp_enabled
                                    ? (this.modelSettings.vlm_mtp_draft_model || null)
                                    : null,
                                vlm_mtp_draft_block_size: this.modelSettings.vlm_mtp_enabled
                                    && this.modelSettings.vlm_mtp_draft_block_size
                                    ? parseInt(this.modelSettings.vlm_mtp_draft_block_size)
                                    : null,
                                trust_remote_code: this.modelSettings.trust_remote_code,
                            };
                            if (isDiffusion) {
                                Object.assign(payload, {
                                    top_p: null,
                                    top_k: null,
                                    repetition_penalty: null,
                                    min_p: null,
                                    presence_penalty: null,
                                    force_sampling: false,
                                    reasoning_parser: null,
                                    index_cache_freq: 0,
                                    enable_thinking: null,
                                    thinking_budget_enabled: false,
                                    thinking_budget_tokens: 0,
                                    guided_grammar_enabled: false,
                                    guided_grammar: null,
                                    max_tool_result_tokens: 0,
                                    turboquant_kv_enabled: false,
                                    turboquant_kv_bits: 4,
                                    specprefill_enabled: false,
                                    specprefill_draft_model: null,
                                    specprefill_keep_pct: null,
                                    specprefill_threshold: null,
                                    dflash_enabled: false,
                                    dflash_draft_model: null,
                                    dflash_draft_quant_enabled: false,
                                    dflash_draft_quant_weight_bits: null,
                                    dflash_draft_quant_activation_bits: null,
                                    dflash_draft_quant_group_size: null,
                                    dflash_max_ctx: null,
                                    dflash_in_memory_cache: true,
                                    dflash_in_memory_cache_max_entries: 4,
                                    dflash_in_memory_cache_max_bytes: 8 * (1024 ** 3),
                                    dflash_ssd_cache: false,
                                    dflash_ssd_cache_max_bytes: 20 * (1024 ** 3),
                                    dflash_draft_window_size: null,
                                    dflash_draft_sink_size: null,
                                    dflash_verify_mode: null,
                                    mtp_enabled: false,
                                    vlm_mtp_enabled: fs] unsupported "
        << "affine quantization group_size=" << group_size << " bits=" << bits
        << ".";
    throw std::invalid_argument(msg.str());
  }

  const int K = x.shape(2);
  const int E = weight.shape(0);
  const int N = weight.shape(1);
  const int packed_bytes = affine_packed_row_bytes(K, bits);
  if (packed_bytes <= 0 ||
      weight.shape(2) * static_cast<int>(sizeof(uint32_t)) != packed_bytes ||
      scales.shape(0) != E || scales.shape(1) != N ||
      scales.shape(2) != K / group_size || biases.shape() != scales.shape()) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_affine_gather_qmm_blocks] "
        << "incompatible shapes: " << x.shape() << ", " << weight.shape()
        << ", " << scales.shape() << ", " << biases.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (x.dtype() != float16 && x.dtype() != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_affine_gather_qmm_blocks] expected "
        << "float16 or bfloat16 input, got " << x.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (weight.dtype() != uint32 || scales.dtype() != x.dtype() ||
      biases.dtype() != x.dtype() || block_meta.dtype() != int32 ||
      block_count.dtype() != int32) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_affine_gather_qmm_blocks] expected "
        << "uint32 weight, scales/biases matching input dtype, int32 "
        << "block_meta/count, got " << weight.dtype() << ", "
        << scales.dtype() << ", " << biases.dtype() << ", "
        << block_meta.dtype() << ", " << block_count.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  std::vector<array> inputs = {
      x, weight, scales, biases, block_meta, block_count};
  if (DeepseekAffineGatherBlocksPrimitive::unsupported(
          x,
          weight,
          scales,
          biases,
          block_meta,
          block_count,
          group_size,
          bits,
          stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_affine_gather_qmm_blocks] unsupported shape.");
  }

  Shape out_shape{x.shape(0), 1, N};
  return array(
      std::move(out_shape),
      x.dtype(),
      std::make_shared<DeepseekAffineGatherBlocksPrimitive>(
          stream, group_size, bits, variant),
      std::move(inputs));
}

array deepseek_affine_gather_qmm_pair_concat_blocks(
    const array& x,
    const array& weight0,
    const array& scales0,
    const array& biases0,
    const array& weight1,
    const array& scales1,
    const array& biases1,
    const array& block_meta,
    const array& block_count,
    int group_size,
    int bits,
    int variant,
    StreamOrDevice s /* = {} */) {
  const auto cfg = mxfp4_blocks_variant(variant);
  auto stream = to_stream(s);
  if (DeepseekAffineGatherPairBlocksPrimitive::unsupported(
          x,
          weight0,
          scales0,
          biases0,
          weight1,
          scales1,
          biases1,
          block_meta,
          block_count,
          group_size,
          bits,
          stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_affine_gather_qmm_pair_concat_blocks] unsupported shape.");
  }
  const int N = weight0.shape(1);
  if (N % cfg.bn != 0) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_affine_gather_qmm_pair_concat_blocks] "
        "output dimension must be divisible by the block N.");
  }
  std::vector<array> inputs = {
      x,
      weight0,
      scales0,
      biases0,
      weight1,
      scales1,
      biases1,
      block_meta,
      block_count};
  Shape out_shape{x.shape(0), 1, 2 * N};
  return array(
      std::move(out_shape),
      x.dtype(),
      std::make_shared<DeepseekAffineGatherPairBlocksPrimitive>(
          stream, group_size, bits, variant),
      std::move(inputs));
}

array deepseek_mxfp4_gather_qmm_expert(
    const array& x,
    const array& weight,
    const array& scales,
    const array& indices,
    int variant,
    StreamOrDevic    corpus = _load_bench_corpus(profile)

    target_chars = max(round(target_tokens * spec.chars_per_token), 1)
    for _ in range(_PROMPT_BUILD_MAX_ATTEMPTS):
        repeats = (target_chars + len(corpus) - 1) // len(corpus)
        body = (corpus * repeats)[:target_chars]
        tokens = [int(token) for token in tokenizer.encode(unique_prefix + body)]
        if len(tokens) >= target_tokens:
            return tokens[:target_tokens]
        if not tokens:
            raise RuntimeError(
                f"Benchmark corpus {profile.value} tokenized to 0 tokens"
            )

        # Scale by the observed tokenizer ratio, rounding up. The +1 guarantees
        # progress even for tokenizers with coarse or unusual segmentation.
        target_chars = max(
            target_chars + 1,
            (target_chars * target_tokens + len(tokens) - 1) // len(tokens) + 1,
        )

    raise RuntimeError(
        f"Could not build an exact {target_tokens}-token benchmark prompt "
        f"after {_PROMPT_BUILD_MAX_ATTEMPTS} attempts"
    )


def _generate_external_prompt(
    target_tokens: int,
    context_profile: (
        BenchmarkContextProfile | str
    ) = BenchmarkContextProfile.CODE_PYTHON,
) -> str:
    """Generate an approximately target_tokens-long prompt without a tokenizer.

    Uses a unique UUID prefix so remote prefix caches cannot skew results.
    """
    unique_prefix = f"BENCH-{uuid.uuid4().hex} "
    profile = BenchmarkContextProfile(context_profile)
    spec = BENCHMARK_CONTEXT_PROFILES[profile]
    corpus = _load_bench_corpus(profile)
    target_chars = max(
        0,
        round(target_tokens * spec.chars_per_token) - len(unique_prefix),
    )
    repeats = (target_chars + len(corpus) - 1) // len(corpus)
    return unique_prefix + (corpus * repeats)[:target_chars]


def _compute_single_metrics(
    prompt_tokens: int,
    completion_tokens: int,
    start_time: float,
    first_token_time: float,
    end_time: float,
    peak_memory: int,
    cached_tokens: int,
    prefill_duration_s: float | None = None,
    generation_duration_s: float | None = None,
    generation_measured: bool = True,
    timing_observed: bool = True,
) -> dict:
    """Compute all metrics for a single request benchmark."""
    ttft_s = first_token_time - start_time
    prefill_duration = prefill_duration_s if prefill_duration_s is not None else ttft_s
    gen_duration = (
        generation_duration_s
        if generation_duration_s is not None
        else end_time - first_token_time
    )
    e2e_duration = end_time - start_time

    ttft_ms: float | None = ttft_s * 1000
    if generation_measured and completion_tokens > 1 and gen_duration > 0:
        tpot_ms: float | None = (gen_duration / (completion_tokens - 1)) * 1000
        gen_tps: float | None = completion_tokens / gen_duration
    else:
        # Generation timing could not be measured (e.g. all content arrived
        # in a single burst with no measurable inter-token span) — report
        # unmeasured rather than a misleading 0.0.
        tpot_ms = None
        gen_tps = None
    processing_tps: float | None = prompt_tokens / max(prefill_duration, 1e-9)
    total_throughput = (prompt_tokens + completion_tokens) / max(e2e_duration, 1e-9)

    if not timing_observed:
        # The first-token timestamp was never observed and fell back to the
        # end of the response, so TTFT covers the whole response and the
        # prefill rate derived from it is not a prefill rate at all. Only
        # e2e latency and total throughput survive.
        ttft_ms = None
        processing_tps = None

    return {
        "ttft_ms": round(ttft_ms, 1) if ttft_ms is not None else None,
        "tpot_ms": round(tpot_ms, 2) if tpot_ms is not None else None,
        "gen_tps": round(gen_tps, 1) if gen_tps is not None else None,
        "processing_tps": (
            round(processing_tps, 1) if processing_tps is not None else None
        ),
        "e2e_latency_s": round(e2e_duration, 3),
        "total_throughput": round(total_throughput, 1),
        "peak_memory_bytes": peak               .foregroundStyle(theme.textSecondary)
                    Spacer(minLength: 0)
                }
            }

            Row(label: String(localized: "bench.context.result.measured",
                              defaultValue: "Admission boundary",
                              comment: "Result row label for the raw measured admission boundary")) {
                Text(result.measuredTokens.formatted())
                    .font(.omlxText(12, weight: .medium))
                    .monospacedDigit()
            }

            Row(label: String(localized: "bench.context.result.verified",
                              defaultValue: "Verified prefill",
                              comment: "Result row label for the prompt size the verification prefill completed")) {
                Text(result.verifiedTokens.formatted())
                    .font(.omlxText(12, weight: .medium))
                    .monospacedDigit()
            }

            Row(label: String(localized: "bench.context.result.prefill_tps",
                              defaultValue: "Prefill speed",
                              comment: "Result row label for the verify prefill's tokens per second")) {
                Text(prefillTpsLabel)
                    .font(.omlxText(12, weight: .medium))
                    .monospacedDigit()
            }

            Row(label: String(localized: "bench.context.result.capped_by",
                              defaultValue: "Limited by",
                              comment: "Result row label for what bounded the measurement")) {
                Text(cappedByLabel)
                    .font(.omlxText(12, weight: .medium))
            }

            Row(label: String(localized: "bench.context.result.duration",
                              defaultValue: "Duration",
                              comment: "Result row label for how long the benchmark took")) {
                Text(durationLabel)
                    .font(.omlxText(12, weight: .medium))
                    .monospacedDigit()
            }

            FreeRow(isLast: true) {
                VStack(alignment: .leading, spacing: 4) {
                    if result.applied {
                        HintLine(text: String(localized: "bench.context.result.applied_note",
                                              defaultValue: "The value has been applied to this model's Context Window setting.",
                                              comment: "Hint under the Context Bench result confirming the setting was written"))
                    }
                    HintLine(text: String(localized: "bench.context.result.snapshot_note",
                                          defaultValue: "The result reflects free memory and the Memory Guard tier at benchmark time; rerun after major changes to either.",
                                          comment: "Hint under the Context Bench result explaining the measurement is a snapshot"))
                }
            }
        }
    }

    private var cappedByLabel: String {
        switch result.cappedBy {
        case "target":
            return String(localized: "bench.context.capped.target",
                          defaultValue: "Selected target",
                          comment: "Limited-by value when the selected target bounded the result")
        case "native":
            return String(localized: "bench.context.capped.native",
                          defaultValue: "Model's native context length",
                          comment: "Limited-by value when the model's own context length bounded the result")
        default:
            return String(localized: "bench.context.capped.memory",
                          defaultValue: "Available memory",
                          comment: "Limited-by value when free memory bounded the result")
        }
    }

    private var prefillTpsLabel: String {
        guard let tps = result.prefillTps, tps > 0 else { return "—" }
        return "\(Int(tps.rounded()).formatted()) tok/s"
    }

    private var durationLabel: String {
        let salse,
                                    vlm_mtp_draft_model: null,
                                    vlm_mtp_draft_block_size: null,
                                });
                            }
                            return payload;
                        })()),
                    });

                    if (response.ok) {
                        // Refresh the model list to update badges
                        await this.loadModels();
                        const data = await response.json();
                        this.showModelSettingsModal = false;
                        if (data.requires_reload) {
                            if (data.auto_reloaded) {
                                alert(window.t('js.info.model_settings_auto_reloaded'));
                            } else if (data.auto_unloaded) {
                                alert(window.t('js.info.model_settings_auto_unloaded'));
                            } else {
                                alert(window.t('js.info.model_type_reload_required'));
                            }
                        }
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        alert(data.detail || window.t('js.error.save_model_settings_failed'));
                    }
                } catch (err) {
                    console.error('Failed to save model settings:', err);
                    alert(window.t('js.error.save_model_settings_failed'));
                } finally {
                    this.savingModelSettings = false;
                }
            },

            async loadGenerationDefaults() {
                if (!this.selectedModel) return;
                this.loadingGenDefaults = true;
                try {
                    const response = await fetch(`/admin/api/models/${encodeURIComponent(this.selectedModel.id)}/generation_config`);
                    if (response.ok) {
                        const data = await response.json();
                        // Set values from config, clear everything else to Default (null)
                        this.modelSettings.max_context_window = data.max_context_window ?? null;
                        this.modelSettings.temperature = data.temperature ?? null;
                        this.modelSettings.top_p = data.top_p ?? null;
                        this.modelSettings.top_k = data.top_k ?? null;
                        this.modelSettings.repetition_penalty = data.repetition_penalty ?? null;
                        this.modelSettings.max_tokens = null;
                        this.modelSettings.min_p = null;
                        this.modelSettings.presence_penalty = null;
                        this.modelSettings.force_sampling = false;
                        this.modelSettings.reasoning_parser = null;
                        this.modelSettings.guided_grammar_enabled = false;
                        this.modelSettings.guided_grammar = '';
                        this.modelSettings.ttl_seconds = null;
                        this.modelSettings.enableIndexCache = false;
                        this.modelSettings.index_cache_freq = 0;
                        this.modelSettings.enable_thinking = false;
                        this.modelSettings.enableThinkingBudget = false;
                        this.modelSettings.thinking_budget_tokens = 0;
                        this.modelSettings.enableToolResultLimit = false;
                        this.modelSettings.max_tool_result_tokens = 0;
                        this.modelSettings.ctKwargEntries = [];
                        this.modelSettings.turboquant_kv_enabled = false;
                        this.modelSettings.turboquant_kv_bits = 4;
                        this.modelSettings.specprefill_enabled = false;
                        this.modelSettings.specprefill_draft_model = null;
                        this.modelSettings.specprefill_keep_pct = 0.2;
                        thise s /* = {} */) {
  (void)mxfp4_blocks_variant(variant);

  if (x.ndim() != 3 || x.shape(1) != 1 || weight.ndim() != 3 ||
      scales.ndim() != 3 || indices.ndim() != 1 ||
      indices.size() != x.shape(0)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_expert] expected "
        << "x [M,1,K], weight [E,N,K/8], scales [E,N,K/32], "
        << "indices [M], got " << x.shape() << ", " << weight.shape() << ", "
        << scales.shape() << ", " << indices.shape() << ".";
    throw std::invalid_argument(msg.str());
  }

  constexpr int bits = 4;
  constexpr int group_size = 32;
  constexpr int values_per_uint32 = 32 / bits;
  const int K = x.shape(2);
  const int E = weight.shape(0);
  const int N = weight.shape(1);
  if (weight.shape(2) * values_per_uint32 != K || scales.shape(0) != E ||
      scales.shape(1) != N || scales.shape(2) != K / group_size) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_expert] "
        << "incompatible shapes: " << x.shape() << ", " << weight.shape()
        << ", " << scales.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (x.dtype() != float16 && x.dtype() != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_expert] expected "
        << "float16 or bfloat16 input, got " << x.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (weight.dtype() != uint32 || scales.dtype() != uint8 ||
      (indices.dtype() != uint32 && indices.dtype() != int32)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_expert] expected "
        << "uint32 weight, uint8 scales, uint32/int32 indices, got "
        << weight.dtype() << ", " << scales.dtype() << ", "
        << indices.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  std::vector<array> inputs = {x, weight, scales, indices};
  if (DeepseekMxfp4GatherExpertPrimitive::unsupported(
          x, weight, scales, indices, stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.deepseek_mxfp4_gather_qmm_expert] unsupported shape.");
  }

  Shape out_shape{x.shape(0), 1, N};
  return array(
      std::move(out_shape),
      x.dtype(),
      std::make_shared<DeepseekMxfp4GatherExpertPrimitive>(stream, variant),
      std::move(inputs));
}

} // namespace omlx::glm_kernels


# ===== FILE: omlx/custom_kernels/glm_moe_dsa/csrc/sparse_mla.cpp =====

#include "sparse_mla.h"

#include <cstdlib>
#include <dlfcn.h>
#include <filesystem>
#include <sstream>

#include "mlx/backend/common/utils.h"
#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"
#include "mlx/utils.h"

namespace omlx::glm_kernels {

namespace {

using namespace mlx::core;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error("Unable to get omlx_glm_kernels binary dir.");
    }
    return std::filesystem::path(info.dli_fname).parent_path().string();
  }();
  return binary_dir;
}

inline int64_t bcast_stride(const array& a, int axis) {
  return a.shape(axis) == 1 ? 0 : a.strides(axis);
}

bool last_dim_contiguous(const array& arr) {
  return arr.strides(-1) == 1;
}

struct GlmDsaSparseMlaParams {
  int B;
  int H;
  int qL;
  int kL;
  int topk;
  int topk_valid_prefix;
  int causal_prefix_indices;
  int has_topk_length;
  int causal_prefix_rows;

  float scale;
  int qL_off;

  int64_t Q_latent_strides[3];
  int64_t Q_pe_strides[3];
  int64_t KV_latent_strides[3];
  int64_t K_pe_strides[3];
  int64_t Topk_strides[3];
  int64_t TopkLength_strides[2];
  int64_t O_strides[3];
};

class GlmDsaSparseMlaAttentionPrimitive : public Primitive {
 public:
  GlmDsaSparseMlaAttentionPrimitive(
      Stream stream,
      float scale,
      bool do_causal,
      bool topk_valid_prefix,
      bool causal_prefix_indices,
      bool has_topk_length,
      int causal_prefix_rows)
   _memory,
        "prompt_tokens": prompt_tokens,
        "completion_tokens": completion_tokens,
        "cached_tokens": cached_tokens,
    }


def _pin_speed_priority(engine_pool: Any) -> bool | None:
    """Force prefill speed priority for the benchmark's duration.

    Throughput numbers measured while the memory-guard throttle shrinks
    prefill chunks are not comparable, so the bench always runs in speed
    mode. The pin lands on the pool's stored scheduler config — the bench
    model is loaded fresh after unload-all, so that is where its Scheduler
    reads the flag from. Returns the previous value for restoration, or
    None when the pool exposes no config (nothing to restore).
    """
    config = getattr(engine_pool, "_scheduler_config", None)
    if config is None:
        return None
    previous = bool(getattr(config, "prefill_speed_priority", False))
    config.prefill_speed_priority = True
    return previous


def _restore_speed_priority(engine_pool: Any, previous: bool | None) -> None:
    """Undo _pin_speed_priority (no-op when the pin never landed)."""
    if previous is None:
        return
    config = getattr(engine_pool, "_scheduler_config", None)
    if config is not None:
        config.prefill_speed_priority = previous


def _get_batch_benchmark_core(engine: Any) -> Any | None:
    """Return the scheduler core when this engine supports batch benchmarks."""
    engine_core = getattr(engine, "_engine", None)
    if engine_core is None:
        return None
    if not callable(getattr(engine_core, "add_request", None)):
        return None
    if not callable(getattr(engine_core, "stream_outputs", None)):
        return None
    return engine_core


async def _send_event(run: BenchmarkRun, event: dict) -> None:
    """Append an event to the run's log and wake any subscribers.

    Sets `run.terminal` when the event ends the stream so subscribers
    can return rather than wait for an event that will never come.
    """
    async with run.cond:
        run.events.append(event)
        if event.get("type") in _BENCH_TERMINAL_TYPES:
            run.terminal = True
        run.cond.notify_all()


async def _run_single_test(
    engine: Any,
    prompt: list[int],
    max_tokens: int,
    pp_len: int,
) -> dict:
    """Run a single request benchmark test and return metrics."""
    if len(prompt) != pp_len:
        raise RuntimeError(
            f"Benchmark prompt length mismatch before pp{pp_len}: "
            f"built {len(prompt)} tokens"
        )

    # Reset peak memory tracking
    try:
        mx.reset_peak_memory()
    except Exception:
        pass

    start_time = time.perf_counter()
    first_token_time = None
    last_generated_token_time = None
    last_output = None
    prev_completion_tokens = 0

    async for output in engine.stream_generate(
        prompt=prompt,
        max_tokens=max_tokens,
        temperature=0.0,
        top_p=1.0,
    ):
        # Detect first generated token via completion_tokens count,
        # not new_text. Some models (e.g. Harmony/gpt-oss) produce
        # protocol tokens that don't yield visible new_text.
        completion_delta = output.completion_tokens - prev_completion_tokens
        if completion_delta > 0:
            generated_at = getattr(output, "generated_at", None)
            generated_until = getattr(output, "generated_until", None)
            output_first_token_time = (
                float(generated_at) if generated_at is not None else time.perf_counter()
            )
            if first_token_time is None:
                first_token_time = output_first_token_time
            if generated_until is not None:
                last_generated_token_time = float(generated_until)
            elif completion_delta == 1:
                last_generated_token_time = output_first_token_time
        prev_completion_tokens = output.completion_tokens
        last_output = output

    end_time = time.perf_counter()

    if first_token_time is None:
        first_token_time = end_time

    # Get peak memory
    try:
        peak_memory = mx.get_peconds = Int(result.durationS.rounded())
        if seconds >= 60 {
            return "\(seconds / 60)m \(seconds % 60)s"
        }
        return "\(seconds)s"
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/DownloadsScreen.swift =====

// PR 8 — Downloads screen.
//
// Wires the HF downloader endpoints (POST /admin/api/hf/download,
// GET /admin/api/hf/tasks at 1 Hz, cancel / retry / delete, /hf/recommended).
//
// Phase 2 — adds a source selector (HF / ModelScope) at the top. The MS
// branch mirrors the HF flow 1:1 against /admin/api/ms/*. Switching the
// source swaps the form + mirror editor; the task list, recent tasks, and
// suggested-models sections rebind to whichever source is active (their
// underlying DTOs are identical — see MSTaskDTO.swift).

import SwiftUI

/// Active downloader source. Mirrors the HTML admin's `downloaderSource`
/// state at `omlx/admin/static/js/dashboard.js:266`.
enum DownloadSource: String, CaseIterable, Hashable, Sendable {
    case hf, ms

    var label: String {
        switch self {
        case .hf: return String(localized: "downloads.source.hf",
                                defaultValue: "Hugging Face",
                                comment: "Source selector option label for Hugging Face")
        case .ms: return String(localized: "downloads.source.ms",
                                defaultValue: "ModelScope",
                                comment: "Source selector option label for ModelScope")
        }
    }
}

struct DownloadsScreen: View {
    @Environment(AppServices.self) private var services
    @State private var vm = DownloadsScreenVM()

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            SourceSwitcher(
                source: $vm.source,
                msAvailable: vm.msAvailable
            )

            if vm.source == .hf {
                AddFromHFSection(
                    repoText: $vm.repoText,
                    isStarting: vm.isStarting,
                    mirrorHost: vm.mirrorHost,
                    mirrorIsCustom: vm.mirrorIsCustom,
                    isEditingMirror: $vm.isEditingMirror,
                    mirrorDraft: $vm.mirrorDraft,
                    mirrorBusy: vm.mirrorBusy,
                    searchResults: vm.searchResults,
                    searchLoading: vm.searchLoading,
                    searchDismissed: vm.searchDismissed,
                    onSubmit: { vm.startDownload(client: services.client) },
                    onSaveMirror: { vm.saveMirror(client: services.client) },
                    onResetMirror: { vm.resetMirror(client: services.client) },
                    onPickResult: { vm.pickSearchResult($0) },
                    onDismissSearch: { vm.dismissSearch() },
                    onShowCard: { repo in vm.showModelCard(repoId: repo) }
                )
                .onChange(of: vm.repoText) { _, newValue in
                    vm.updateSearch(query: newValue, client: services.client)
                }
            } else {
                AddFromMSSection(
                    repoText: $vm.msRepoText,
                    isStarting: vm.isStarting,
                    mirrorHost: vm.msMirrorHost,
                    mirrorIsCustom: vm.msMirrorIsCustom,
                    isEditingMirror: $vm.isEditingMsMirror,
                    mirrorDraft: $vm.msMirrorDraft,
                    mirrorBusy: vm.msMirrorBusy,
                    searchResults: vm.msSearchResults,
                    searchLoading: vm.msSearchLoading,
                    searchDismissed: vm.msSearchDismissed,
                    onSubmit: { vm.startDownload(client: services.client) },
                    onSaveMirror: { vm.saveMsMirror(client: services.client) },
                    onResetMirror: { vm.resetMsMirror(client: services.client) },
                    onPickResult: { vm.pickMsSearchResult($0) },
                    onDismissSearch: { vm.dismissMsSearch() },
                    onShowCard: { repo in vm.showModelCard(repoId: repo) }
                )
                .onChan.modelSettings.specprefill_threshold = null;
                        this.modelSettings.dflash_enabled = false;
                        this.modelSettings.dflash_draft_model = null;
                        this.modelSettings.dflash_draft_quant_enabled = false;
                        this.modelSettings.dflash_draft_quant_weight_bits = null;
                        this.modelSettings.dflash_draft_quant_activation_bits = null;
                        this.modelSettings.dflash_draft_quant_group_size = null;
                        this.modelSettings.dflash_max_ctx = null;
                        this.modelSettings.dflash_in_memory_cache = true;
                        this.modelSettings.dflash_in_memory_cache_max_entries = 4;
                        this.modelSettings.dflash_in_memory_cache_max_gib = 8;
                        this.modelSettings.dflash_ssd_cache = false;
                        this.modelSettings.dflash_ssd_cache_max_gib = 20;
                        this.modelSettings.dflash_draft_window_size = null;
                        this.modelSettings.dflash_draft_sink_size = null;
                        this.modelSettings.dflash_verify_mode = 'adaptive';
                        this.modelSettings.mtp_enabled = false;
                        this.modelSettings.trust_remote_code = false;
                    } else if (response.status === 404) {
                        alert(window.t('js.error.no_config_defaults'));
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        alert(data.detail || window.t('js.error.load_generation_config_failed'));
                    }
                } catch (err) {
                    console.error('Failed to load generation config:', err);
                    alert(window.t('js.error.load_generation_config_failed'));
                } finally {
                    this.loadingGenDefaults = false;
                }
                this.activeProfileName = null;
                this.profilesDrift = false;
            },

            // Status tab functions
            // Normalizes a host string for safe URL embedding:
            //  - unwraps existing IPv6 brackets so we can re-bracket consistently
            //  - maps unspecified bind addresses (0.0.0.0, ::) to a placeholder
            //    since they are not routable from a client
            //  - maps `localhost` to 127.0.0.1 for consistency with other URLs
            //  - bracket-wraps IPv6 addresses per RFC 3986 (`http://[::1]:8000/v1`)
            formatDisplayHost(host) {
                const value = (host || '').trim();
                if (!value) return '127.0.0.1';

                const unwrapped = value.startsWith('[') && value.endsWith(']')
                    ? value.slice(1, -1)
                    : value;

                if (unwrapped === '0.0.0.0' || unwrapped === '::') return 'your-ip-address';
                if (unwrapped === 'localhost') return '127.0.0.1';
                if (unwrapped.includes(':')) return `[${unwrapped}]`;
                return unwrapped;
            },

            get displayHost() {
                const host = this.selectedAlias || this.stats.host || '127.0.0.1';
                return this.formatDisplayHost(host);
            },

            get ttlPlaceholder() {
                if (this.selectedModel?.pinned) return window.t('modal.model_settings.ttl_pinned');
                const globalTtl = this.globalSettings.idle_timeout?.idle_timeout_seconds;
                if (globalTtl) {
                    return window.t('modal.model_settings.ttl_global_fallback').replace('{seconds}', globalTtl);
                }
                return window.t('modal.model_settings.ttl_no_ttl');
            },

            async loadServerInfo() {
                try {
                    const response = await fetch('/admin/api/server-info');
                    if (response.ok) {
                        const data = await re   : Primitive(stream),
        scale_(scale),
        do_causal_(do_causal),
        topk_valid_prefix_(topk_valid_prefix),
        causal_prefix_indices_(causal_prefix_indices),
        has_topk_length_(has_topk_length),
        causal_prefix_rows_(causal_prefix_rows) {}

  static bool unsupported(
      const array& q_latent,
      const array& q_pe,
      const array& kv_latent,
      const array& k_pe,
      const array& topk_indices,
      const std::optional<array>& topk_length,
      bool topk_valid_prefix,
      bool causal_prefix_indices,
      int causal_prefix_rows,
      bool do_causal,
      Stream s) {
    if (s.device == Device::cpu || !do_causal) {
      return true;
    }
    if (q_latent.dtype() != q_pe.dtype() ||
        q_latent.dtype() != kv_latent.dtype() ||
        q_latent.dtype() != k_pe.dtype()) {
      return true;
    }
    if (q_latent.dtype() != float16 && q_latent.dtype() != bfloat16) {
      return true;
    }
    if (q_latent.ndim() != 4 || q_pe.ndim() != 4 || kv_latent.ndim() != 4 ||
        k_pe.ndim() != 4 || topk_indices.ndim() != 4) {
      return true;
    }
    if (!last_dim_contiguous(q_latent) || !last_dim_contiguous(q_pe) ||
        !last_dim_contiguous(kv_latent) || !last_dim_contiguous(k_pe) ||
        !last_dim_contiguous(topk_indices)) {
      return true;
    }
    if ((q_latent.shape(1) != 64 && q_latent.shape(1) != 32) ||
        kv_latent.shape(1) != 1 || k_pe.shape(1) != 1 ||
        topk_indices.shape(1) != 1) {
      return true;
    }
    if (q_latent.shape(3) != 512 || kv_latent.shape(3) != 512 ||
        q_pe.shape(3) != 64 || k_pe.shape(3) != 64) {
      return true;
    }
    if (q_latent.shape(2) <= 1 || topk_indices.shape(3) < 16 ||
        topk_indices.dtype() != uint32) {
      return true;
    }
    if (causal_prefix_rows < 0 || causal_prefix_rows > q_latent.shape(2)) {
      return true;
    }
    const bool compact_prefix =
        causal_prefix_rows > 0 && topk_indices.shape(2) != q_latent.shape(2);
    if (compact_prefix) {
      if (!causal_prefix_indices || !topk_valid_prefix ||
          topk_indices.shape(2) + causal_prefix_rows != q_latent.shape(2)) {
        return true;
      }
    } else if (topk_indices.shape(2) != q_latent.shape(2)) {
      return true;
    }
    if (topk_length.has_value() &&
        (topk_length->dtype() != uint32 ||
         (topk_length->ndim() != 2 && topk_length->ndim() != 3))) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error(
        "GlmDsaSparseMlaAttentionPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);

    const auto& q_latent = inputs[0];
    const auto& q_pe = inputs[1];
    const auto& kv_latent = inputs[2];
    const auto& k_pe = inputs[3];
    const auto& topk = inputs[4];
    const bool has_topk_length = inputs.size() > 5;
    const array& topk_length = has_topk_length ? inputs[5] : topk;
    auto& o = outputs[0];

    // BK sets the key-tile size AND the threadgroup-memory footprint (KV slab
    // ~= BK*(DC+pad)*2B). At BK=256 the 32-head variant uses ~24KB -> only ONE
    // threadgroup resident per core on Apple GPUs, so its ~500 barrier-separated
    // staging phases serialize with nothing to hide behind. BK=128 halves the
    // slab -> 2 resident threadgroups -> measured 100.3 -> 83.2 ms per layer-call
    // at S=131k (real top-k index patterns, M3 Ultra), 85.4 ms at S=303k; output
    // differs from BK=256 only in bf16 summation-order rounding (identical error
    // vs fp32 ground-truth attention). BK=64 over-fragments (102 ms). The 64-head
    // variant keeps BK=256, and not because its slab is smaller: at ~26KB it is
    // in the same one-threadgroup-per-core situation. It just runs wm=8, so a
    // single threadgroup already holds 256 threads and fills the core, and
    // halving BK only fragments teak_memory()
    except Exception:
        peak_memory = 0

    if last_output is None:
        raise RuntimeError(f"Benchmark pp{pp_len} produced no engine output")

    prompt_tokens = last_output.prompt_tokens
    if prompt_tokens != pp_len:
        raise RuntimeError(
            f"Benchmark prompt length mismatch after pp{pp_len}: "
            f"engine reported {prompt_tokens} tokens"
        )

    completion_tokens = last_output.completion_tokens
    cached_tokens = last_output.cached_tokens

    if cached_tokens > 0:
        logger.warning(
            f"Benchmark test pp{pp_len} had {cached_tokens} cached tokens "
            f"(expected 0). Results may not reflect true prefill performance."
        )

    prefill_duration_s = None
    generation_duration_s = None
    producer_generation_duration_s = None
    metric_completion_tokens = completion_tokens
    if first_token_time is not None and last_generated_token_time is not None:
        measured_duration = last_generated_token_time - first_token_time
        if measured_duration > 0:
            producer_generation_duration_s = measured_duration
    if last_output is not None:
        prompt_tps = float(getattr(last_output, "prompt_tps", 0.0) or 0.0)
        if prompt_tps > 0 and prompt_tokens > 0:
            prefill_duration_s = prompt_tokens / prompt_tps

        canvas_tps = float(getattr(last_output, "diffusion_canvas_tps", 0.0) or 0.0)
        canvas_tokens = int(getattr(last_output, "diffusion_canvas_tokens", 0) or 0)
        if canvas_tps > 0 and canvas_tokens > 0:
            metric_completion_tokens = canvas_tokens
            generation_duration_s = canvas_tokens / canvas_tps
        else:
            generation_tps = float(getattr(last_output, "generation_tps", 0.0) or 0.0)
            if generation_tps > 0 and completion_tokens > 0:
                generation_duration_s = completion_tokens / generation_tps

    if generation_duration_s is None:
        generation_duration_s = producer_generation_duration_s

    generation_measured = generation_duration_s is not None

    return _compute_single_metrics(
        prompt_tokens=prompt_tokens,
        completion_tokens=metric_completion_tokens,
        start_time=start_time,
        first_token_time=first_token_time,
        end_time=end_time,
        peak_memory=peak_memory,
        cached_tokens=cached_tokens,
        prefill_duration_s=prefill_duration_s,
        generation_duration_s=generation_duration_s,
        generation_measured=generation_measured,
    )


async def _run_batch_test(
    engine: Any,
    prompts: list[list[int]],
    prompt_tokens: int,
    max_tokens: int,
    batch_size: int,
) -> dict:
    """Run a continuous batching benchmark test.

    Submits batch_size concurrent requests via the engine core and measures
    aggregate throughput including pp TPS and tg TPS.

    Args:
        prompts: List of prompts (one per request). For same-prompt tests,
                 all entries are identical. For different-prompt tests, each
                 has a unique UUID prefix.
        prompt_tokens: Number of prompt tokens per request (for pp TPS calc).
    """
    from ..request import SamplingParams

    engine_core = _get_batch_benchmark_core(engine)
    if engine_core is None:
        raise ValueError("Engine does not support batch benchmarks")
    if len(prompts) < batch_size:
        raise RuntimeError(
            f"Benchmark batch requires {batch_size} prompts, got {len(prompts)}"
        )
    invalid_lengths = [
        len(prompt) for prompt in prompts[:batch_size] if len(prompt) != prompt_tokens
    ]
    if invalid_lengths:
        raise RuntimeError(
            f"Benchmark batch prompt length mismatch: expected {prompt_tokens}, "
            f"got {invalid_lengths}"
        )

    sampling_params = SamplingParams(
        max_tokens=max_tokens,
        temperature=0.0,
        top_p=1.0,
    )

    async def _single_request(prompt: list[int]) -> dict:
        """Run a single request within the batch."""
        start = time.perf_counter()
        first_token = None
     ge(of: vm.msRepoText) { _, newValue in
                    vm.updateMsSearch(query: newValue, client: services.client)
                }
            }

            ActiveDownloadsSection(
                tasks: vm.activeTasks,
                onCancel: { id in vm.cancel(taskId: id, client: services.client) },
                onRemove: { id in vm.remove(taskId: id, client: services.client) }
            )

            CompletedTasksSection(
                tasks: vm.terminalTasks,
                onRetry: { id in vm.retry(taskId: id, client: services.client) },
                onRemove: { id in vm.remove(taskId: id, client: services.client) },
                onShowCard: { repo in vm.showModelCard(repoId: repo) }
            )

            SuggestedSection(
                models: vm.sortedRecommended,
                sort: $vm.recommendedSort,
                isLoading: vm.recommendedLoading,
                onGet: { repo in vm.startDownload(repo: repo, client: services.client) },
                onRefresh: { Task { await vm.loadRecommended(client: services.client) } },
                onShowCard: { repo in vm.showModelCard(repoId: repo) }
            )

            if let error = vm.lastError {
                Text(error)
                    .font(.omlxText(11))
                    .foregroundStyle(.red)
                    .padding(.horizontal, 18)
                    .padding(.top, 8)
            }
        }
        .task { await vm.start(client: services.client) }
        .onDisappear { vm.stop() }
        .sheet(item: $vm.modelCardTarget) { target in
            ModelCardSheet(
                target: target,
                client: services.client,
                onDownload: { repo in
                    // Sheet dismisses itself before this fires; the
                    // download lands in the Active section under
                    // whichever source the sheet was opened from.
                    vm.startDownload(repo: repo, client: services.client)
                }
            )
        }
    }
}

// MARK: - Source switcher

/// Segmented HF / ModelScope toggle pinned at the top of Downloads. When
/// the server's modelscope SDK isn't installed (`/admin/api/ms/status`
/// returns `available: false`), the MS option is disabled with a tooltip
/// rather than hidden — so a user looking for it can see why it's not
/// usable.
private struct SourceSwitcher: View {
    @Binding var source: DownloadSource
    let msAvailable: Bool

    var body: some View {
        HStack(spacing: 8) {
            Segmented(
                selection: $source,
                options: DownloadSource.allCases.map { ($0, $0.label) }
            )
            .disabled(!msAvailable)
            if !msAvailable {
                Text(String(localized: "downloads.source.ms_unavailable",
                            defaultValue: "ModelScope SDK unavailable in this build",
                            comment: "Inline note shown beside the source switcher when the ModelScope SDK isn't installed"))
                    .font(.omlxText(10.5))
                    .foregroundStyle(.secondary)
            }
            Spacer(minLength: 0)
        }
        .padding(.horizontal, 14)
        .padding(.top, 4)
        .padding(.bottom, 8)
    }
}

// MARK: - Add from HF

private struct AddFromHFSection: View {
    @Binding var repoText: String
    let isStarting: Bool
    let mirrorHost: String
    let mirrorIsCustom: Bool
    @Binding var isEditingMirror: Bool
    @Binding var mirrorDraft: String
    let mirrorBusy: Bool
    let searchResults: [HFModelInfo]
    let searchLoading: Bool
    let searchDismissed: Bool
    let onSubmit: () -> Void
    let onSaveMirror: () -> Void
    let onResetMirror: () -> Void
    let onPickResult: (HFModelInfo) -> Void
    let onDismissSearch: () -> Void
    let onShowCard: (String) -> Void

    @Environment(\.omlxTheme) private var theme
    @FocusState private var mirrorFocused: Bool

    private var showsDropdown: Bool {
        !searchDismissed && (searchLoading || !searchResults.isEmpty)
    }

    var bodysponse.json();
                        const aliases = Array.isArray(data.aliases) ? data.aliases : [];
                        this.serverAliases = aliases;
                        // Preserve user selection across reloads if still valid;
                        // otherwise default to the first alias when available.
                        if (this.selectedAlias && !aliases.includes(this.selectedAlias)) {
                            this.selectedAlias = '';
                        }
                        if (!this.selectedAlias && aliases.length > 0) {
                            this.selectedAlias = aliases[0];
                        }
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (err) {
                    console.error('Failed to load server info:', err);
                }
            },

            async restartServerStart() {
                if (this.restartServer.status === 'restarting'
                    || this.restartServer.status === 'waiting') {
                    return;
                }
                if (!window.confirm(window.t('settings.server.restart_confirm'))) {
                    return;
                }

                this.restartServer = {
                    status: 'restarting',
                    message: window.t('settings.server.restart_status_sending'),
                };

                let response;
                try {
                    response = await fetch('/admin/api/server/restart', { method: 'POST' });
                } catch (err) {
                    // Network errors mid-restart are expected if the server
                    // dies before sending the 202; fall through to polling.
                    this.restartServer = {
                        status: 'waiting',
                        message: window.t('settings.server.restart_status_waiting'),
                    };
                    this._restartServerPoll();
                    return;
                }

                if (response.status === 503) {
                    let msg = window.t('settings.server.restart_status_unavailable');
                    try {
                        const data = await response.json();
                        if (data && data.detail) msg = data.detail;
                    } catch (e) { /* ignore */ }
                    this.restartServer = { status: 'unsupported', message: msg };
                    return;
                }

                if (response.status === 401) {
                    window.location.href = '/admin';
                    return;
                }

                if (response.status !== 202) {
                    this.restartServer = {
                        status: 'error',
                        message: window.t('settings.server.restart_status_unexpected')
                            .replace('{status}', String(response.status)),
                    };
                    return;
                }

                this.restartServer = {
                    status: 'waiting',
                    message: window.t('settings.server.restart_status_waiting'),
                };
                this._restartServerPoll();
            },

            _restartServerPoll() {
                const deadline = Date.now() + 60000;  // 60s max wait
                let sawDownAt = 0;
                const tick = async () => {
                    if (Date.now() > deadline) {
                        this.restartServer = {
                            status: 'error',
                            message: window.t('settings.server.restart_status_timeout'),
                        };
                        return;
                    }
                    let alive = false;
                    try {
                        const r = await fetch('/health', { cache: 'no-store' });
                        alive = r.ok;
                    } catch (e) {
                        alive = false;
                    }
                    if (!alive) {
     he K tile into more barrier-separated phases
    // (measured 2-9% slower at BK=128 and 10-29% slower at BK=64, across
    // qL=512..8192 and four top-k index layouts on an M3 Ultra).
    const int bk = (q_latent.shape(1) == 32) ? 128 : 256;
    constexpr int dc = 32;
    constexpr int d_latent = 512;
    constexpr int d_pe = 64;

    const int B = q_latent.shape(0);
    const int H = q_latent.shape(1);
    const int h = H;                  // head count selects the kernel instantiation
    const int wm = (H == 64) ? 8 : 4; // TQ = H / (wm * 8) must be >= 1: 64->8, 32->4
    const int qL = q_latent.shape(2);
    const int kL = kv_latent.shape(2);
    int64_t topk_length_strides[2] = {0, 0};
    if (has_topk_length) {
      topk_length_strides[0] = topk_length.strides(0);
      topk_length_strides[1] =
          topk_length.ndim() == 3 ? topk_length.strides(2)
                                  : topk_length.strides(1);
    }

    int64_t str_oD = 1;
    int64_t str_oL = o.shape(3);
    int64_t str_oH = o.shape(2) * str_oL;
    int64_t str_oB = o.shape(1) * str_oH;
    size_t data_size = o.shape(0) * str_oB;

    array::Flags flags{
        /* bool contiguous = */ 1,
        /* bool row_contiguous = */ 1,
        /* bool col_contiguous = */ 0,
    };

    o.set_data(
        allocator::malloc(o.nbytes()),
        data_size,
        {str_oB, str_oH, str_oL, str_oD},
        flags);

    const bool do_causal = do_causal_;
    metal::MTLFCList func_consts = {
        {&do_causal, MTL::DataType::DataTypeBool, 301},
    };

    std::string base_name;
    concatenate(
        base_name,
        "steel_sparse_mla_",
        type_to_name(q_latent),
        "_bk",
        bk,
        "_dc",
        dc,
        "_h",
        h,
        "_d",
        d_latent,
        "_pe",
        d_pe,
        "_wm",
        wm);

    std::string hash_name;
    concatenate(
        hash_name,
        base_name,
        "_do_causal_",
        (do_causal ? 't' : 'n'));

    auto lib = d.get_library("omlx_glm_kernels", current_binary_dir());
    auto& compute_encoder = metal::get_command_encoder(s);
    auto kernel = d.get_kernel(base_name, lib, hash_name, func_consts);
    compute_encoder.set_compute_pipeline_state(kernel);

    GlmDsaSparseMlaParams params{
        /* int B = */ B,
        /* int H = */ H,
        /* int qL = */ qL,
        /* int kL = */ kL,
        /* int topk = */ topk.shape(3),
        /* int topk_valid_prefix = */ topk_valid_prefix_,
        /* int causal_prefix_indices = */ causal_prefix_indices_,
        /* int has_topk_length = */ has_topk_length,
        /* int causal_prefix_rows = */ causal_prefix_rows_,

        /* float scale = */ scale_,
        /* int qL_off = */ kL - qL,

        /* int64_t Q_latent_strides[3] = */ {
            q_latent.strides(0), q_latent.strides(1), q_latent.strides(2)},
        /* int64_t Q_pe_strides[3] = */ {
            q_pe.strides(0), q_pe.strides(1), q_pe.strides(2)},
        /* int64_t KV_latent_strides[3] = */ {
            kv_latent.strides(0),
            bcast_stride(kv_latent, 1),
            kv_latent.strides(2)},
        /* int64_t K_pe_strides[3] = */ {
            k_pe.strides(0), bcast_stride(k_pe, 1), k_pe.strides(2)},
        /* int64_t Topk_strides[3] = */ {
            topk.strides(0), bcast_stride(topk, 1), topk.strides(2)},
        /* int64_t TopkLength_strides[2] = */ {
            topk_length_strides[0], topk_length_strides[1]},
        /* int64_t O_strides[3] = */ {
            o.strides(0), o.strides(1), o.strides(2)}};

    compute_encoder.set_input_array(q_latent, 0);
    compute_encoder.set_input_array(q_pe, 1);
    compute_encoder.set_input_array(kv_latent, 2);
    compute_encoder.set_input_array(k_pe, 3);
    compute_encoder.set_input_array(topk, 4);
    compute_encoder.set_input_array(topk_length, 5);
    compute_encoder.set_output_array(o, 6);
    compute_encoder.set_bytes(params, 7);

    MTL::Size grid_dims = MTL::Size(qL, B, 1);
    MTL::Size group_dims = MTL::Size(32, wm, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NA   tokens = 0
        prev_tokens = 0
        reported_prompt_tokens = 0

        request_id = await engine_core.add_request(
            prompt=prompt,
            sampling_params=sampling_params,
        )

        async for output in engine_core.stream_outputs(request_id):
            if first_token is None and output.completion_tokens > prev_tokens:
                first_token = time.perf_counter()
            prev_tokens = output.completion_tokens
            if output.finished:
                tokens = output.completion_tokens
                reported_prompt_tokens = output.prompt_tokens

        end = time.perf_counter()
        if first_token is None:
            first_token = end
        if reported_prompt_tokens != prompt_tokens:
            raise RuntimeError(
                f"Benchmark batch prompt length mismatch after submission: "
                f"expected {prompt_tokens}, engine reported "
                f"{reported_prompt_tokens}"
            )

        return {
            "ttft_s": first_token - start,
            "first_token_abs": first_token,
            "end_abs": end,
            "completion_tokens": tokens,
        }

    # Submit all requests concurrently. Nothing else generates during the
    # gather, so the process-global peak counter belongs to this batch.
    if HAS_MLX:
        try:
            mx.reset_peak_memory()
        except Exception:
            pass
    wall_start = time.perf_counter()
    results = await asyncio.gather(
        *[_single_request(prompts[i]) for i in range(batch_size)]
    )
    wall_end = time.perf_counter()
    peak_memory = 0
    if HAS_MLX:
        try:
            peak_memory = mx.get_peak_memory()
        except Exception:
            peak_memory = 0

    # Aggregate metrics
    total_gen_tokens = sum(r["completion_tokens"] for r in results)
    total_prompt_tokens = prompt_tokens * batch_size
    wall_time = wall_end - wall_start
    avg_ttft_ms = (sum(r["ttft_s"] for r in results) / batch_size) * 1000

    # pp TPS: total prompt tokens / time until ALL requests finish prefill
    max_first_token = max(r["first_token_abs"] for r in results)
    prefill_wall_time = max_first_token - wall_start
    pp_tps = total_prompt_tokens / max(prefill_wall_time, 1e-9)

    # tg TPS: total generated tokens / generation wall time
    # Generation starts when the last request finishes prefill
    gen_wall_time = wall_end - max_first_token
    tg_tps = total_gen_tokens / max(gen_wall_time, 1e-9)

    return {
        "pp_tps": round(pp_tps, 1),
        "tg_tps": round(tg_tps, 1),
        "avg_ttft_ms": round(avg_ttft_ms, 1),
        "e2e_latency_s": round(wall_time, 3),
        "peak_memory_bytes": peak_memory,
        "total_gen_tokens": total_gen_tokens,
        "batch_size": batch_size,
    }


async def _run_external_single_test(
    client: ExternalAPIClient,
    prompt: str,
    max_tokens: int,
) -> dict:
    """Run a single-request benchmark against an external endpoint.

    Token counts come from the endpoint's streamed usage payload, never
    from counting SSE chunks (providers batch multiple tokens per chunk).
    Prefill duration is not observable remotely, so pp TPS falls back to
    prompt_tokens / TTFT (network latency included). Peak memory is not
    measurable for a remote host.
    """
    stats = await client.stream_chat_completion(
        messages=[{"role": "user", "content": prompt}],
        max_tokens=max_tokens,
        temperature=0.0,
    )
    gen_duration = stats.last_content_time - stats.first_content_time
    metrics = _compute_single_metrics(
        prompt_tokens=stats.prompt_tokens,
        completion_tokens=stats.completion_tokens,
        start_time=stats.start_time,
        first_token_time=stats.first_content_time,
        end_time=stats.end_time,
        peak_memory=0,
        cached_tokens=stats.cached_tokens,
        prefill_duration_s=None,
        generation_duration_s=gen_duration if gen_duration > 0 else None,
        generation_measured=gen_duration > 0,
        timing_observed=stats.content_observed,
    )
    metrics["p: some View {
        SectionHeader(String(localized: "downloads.hf.section.title",
                              defaultValue: "Add Model from Hugging Face",
                              comment: "Section heading above the Hugging Face download form"))

        ListGroup {
            FreeRow(isLast: true) {
                VStack(alignment: .leading, spacing: 10) {
                    HStack(spacing: 8) {
                        TextInput(
                            text: $repoText,
                            placeholder: "mlx-community/Llama-3.2-3B-Instruct-4bit",
                            mono: true
                        )
                        .frame(maxWidth: .infinity)
                        .onSubmit(onSubmit)
                        if searchLoading {
                            ProgressView()
                                .controlSize(.small)
                                .padding(.trailing, 2)
                        }
                        Button {
                            onSubmit()
                        } label: {
                            Label(String(localized: "downloads.button.download",
                                         defaultValue: "Download",
                                         comment: "Primary button that starts downloading the entered repo"),
                                  systemImage: "icloud.and.arrow.down")
                                .labelStyle(.titleAndIcon)
                        }
                        .buttonStyle(.omlx(.primary))
                        .disabled(repoText.isEmpty || isStarting)
                    }
                    if showsDropdown {
                        SearchDropdown(
                            results: searchResults,
                            isLoading: searchLoading,
                            onPick: onPickResult,
                            onDismiss: onDismissSearch,
                            onShowCard: onShowCard
                        )
                    }
                    if isEditingMirror {
                        mirrorEditor
                    } else {
                        mirrorSummary
                    }
                }
            }
        }
    }

    private var mirrorSummary: some View {
        HStack(spacing: 8) {
            Image(systemName: "globe")
                .font(.system(size: 11))
                .foregroundStyle(theme.textTertiary)
            Text(String(localized: "downloads.mirror.label",
                        defaultValue: "Mirror:",
                        comment: "Inline label preceding the mirror host on the Downloads screen"))
                .font(.omlxText(11))
                .foregroundStyle(theme.textTertiary)
            Text(mirrorHost)
                .font(.omlxMono(11))
                .foregroundStyle(theme.textSecondary)
            if mirrorIsCustom {
                Text(String(localized: "downloads.mirror.custom",
                            defaultValue: "custom",
                            comment: "Badge shown next to the mirror host when the user has configured a custom endpoint"))
                    .font(.omlxText(10, weight: .medium))
                    .foregroundStyle(theme.blueDot)
                    .padding(.horizontal, 5)
                    .padding(.vertical, 1)
                    .background(theme.blueDot.opacity(0.12))
                    .clipShape(Capsule())
            }
            Spacer(minLength: 8)
            Button(String(localized: "downloads.mirror.configure",
                          defaultValue: "Configure mirror…",
                          comment: "Button that opens the inline mirror editor")) {
                mirrorDraft = mirrorIsCustom ? mirrorHost : ""
                isEditingMirror = true
            }
            .buttonStyle(.omlx(.plain, size: .small))
            .disabled(mirrorBusy)
        }
    }

    private var mirrorEditor: some View {
        HStack(spacing: 8) {
            TextInput(
                text: $mirrorDraft,
                placeholder: String(localized: "downloads.                   // First time we see it down — record it. We require a
                        // down-then-up transition before declaring success, so
                        // a fast supervisor that hasn't killed the old process
                        // yet doesn't trick us into "instant success".
                        if (!sawDownAt) sawDownAt = Date.now();
                        setTimeout(tick, 1000);
                        return;
                    }
                    // Alive again. If we never observed the down state, the
                    // restart hasn't actually fired yet — keep polling.
                    if (!sawDownAt) {
                        setTimeout(tick, 1000);
                        return;
                    }
                    this.restartServer = {
                        status: 'idle',
                        message: window.t('settings.server.restart_status_back'),
                    };
                    // Small delay so the user sees the success state, then
                    // reload to ensure all caches/sessions re-sync.
                    setTimeout(() => window.location.reload(), 500);
                };
                tick();
            },

            get llmModels() {
                return this.models.filter(m => m.model_type === 'llm' || m.model_type === 'vlm' || !m.model_type);
            },

            shellQuote(value) {
                const s = String(value ?? '');
                if (!s) return "''";
                return `'${s.replace(/'/g, `'"'"'`)}'`;
            },

            shellEnvAssign(name, value) {
                return `${name}=${this.shellQuote(value)}`;
            },

            get claudeCodeCommand() {
                const mode = this.globalSettings.claude_code.mode;
                if (mode === 'cloud') {
                    return 'env -u ANTHROPIC_BASE_URL -u ANTHROPIC_AUTH_TOKEN -u ANTHROPIC_DEFAULT_OPUS_MODEL -u ANTHROPIC_DEFAULT_SONNET_MODEL -u ANTHROPIC_DEFAULT_HAIKU_MODEL -u API_TIMEOUT_MS -u CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC claude';
                }
                // Local mode
                const port = this.stats.port || 8000;
                const opusModel = this.globalSettings.claude_code.opus_model || 'select-a-model';
                const sonnetModel = this.globalSettings.claude_code.sonnet_model || 'select-a-model';
                const haikuModel = this.globalSettings.claude_code.haiku_model || 'select-a-model';
                const parts = [];
                parts.push(this.shellEnvAssign('ANTHROPIC_BASE_URL', `http://${this.displayHost}:${port}`));
                if (this.stats.api_key) {
                    parts.push(this.shellEnvAssign('ANTHROPIC_AUTH_TOKEN', this.stats.api_key));
                }
                parts.push(this.shellEnvAssign('ANTHROPIC_DEFAULT_OPUS_MODEL', opusModel));
                parts.push(this.shellEnvAssign('ANTHROPIC_DEFAULT_SONNET_MODEL', sonnetModel));
                parts.push(this.shellEnvAssign('ANTHROPIC_DEFAULT_HAIKU_MODEL', haikuModel));
                parts.push('API_TIMEOUT_MS=3000000');
                parts.push('CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1');
                // Deny LSP: its schema joins the tools array mid-session and
                // re-prefills the whole conversation on a caching server (#2349).
                parts.push('claude --disallowedTools LSP');
                return parts.join(' ');
            },

            async saveClaudeCodeSettings() {
                try {
                    const response = await fetch('/admin/api/global-settings', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            claude_code_mode: this.globalSettings.claude_code.mode,
                            claude_code_opus_model: this.globalSettings.claude_code.opus_model,
                            claude_code_sonnet_model: this.globalSettings.claude_code.sonnet_model,
                            claude_cME(OMLXGlmDsaSparseMlaAttention)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs =
        static_cast<const GlmDsaSparseMlaAttentionPrimitive&>(other);
    return scale_ == rhs.scale_ && do_causal_ == rhs.do_causal_ &&
        topk_valid_prefix_ == rhs.topk_valid_prefix_ &&
        causal_prefix_indices_ == rhs.causal_prefix_indices_ &&
        has_topk_length_ == rhs.has_topk_length_ &&
        causal_prefix_rows_ == rhs.causal_prefix_rows_;
  }
  auto state() const {
    return std::make_tuple(
        nullptr,
        scale_,
        do_causal_,
        topk_valid_prefix_,
        causal_prefix_indices_,
        has_topk_length_,
        causal_prefix_rows_);
  }

 private:
  float scale_;
  bool do_causal_;
  bool topk_valid_prefix_;
  bool causal_prefix_indices_;
  bool has_topk_length_;
  int causal_prefix_rows_;
};

} // namespace

array glm_dsa_sparse_mla_attention(
    const array& q_latent,
    const array& q_pe,
    const array& kv_latent,
    const array& k_pe,
    const array& topk_indices,
    float scale,
    bool causal,
    bool topk_valid_prefix,
    bool causal_prefix_indices,
    const std::optional<array>& topk_length,
    int causal_prefix_rows,
    StreamOrDevice s) {
  for (const auto& tensor : {q_latent, q_pe, kv_latent, k_pe}) {
    if (tensor.ndim() != 4) {
      std::ostringstream msg;
      msg << "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] input with shape "
          << tensor.shape() << " expected to be rank 4.";
      throw std::invalid_argument(msg.str());
    }
  }
  if (topk_indices.ndim() != 4) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] topk_indices with "
        << "shape " << topk_indices.shape() << " expected to be rank 4.";
    throw std::invalid_argument(msg.str());
  }
  if (causal_prefix_rows < 0 || causal_prefix_rows > q_latent.shape(2)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] "
        << "causal_prefix_rows must be in [0, L], got "
        << causal_prefix_rows << " for L=" << q_latent.shape(2) << ".";
    throw std::invalid_argument(msg.str());
  }
  const bool compact_prefix_topk =
      causal_prefix_rows > 0 && topk_indices.shape(2) != q_latent.shape(2);
  const bool topk_length_ok = topk_indices.shape(2) == q_latent.shape(2) ||
      (compact_prefix_topk &&
       topk_indices.shape(2) + causal_prefix_rows == q_latent.shape(2) &&
       causal_prefix_indices && topk_valid_prefix);
  if (q_latent.shape(0) != q_pe.shape(0) ||
      q_latent.shape(0) != kv_latent.shape(0) ||
      q_latent.shape(0) != k_pe.shape(0) ||
      q_latent.shape(0) != topk_indices.shape(0) ||
      q_latent.shape(1) != q_pe.shape(1) || kv_latent.shape(1) != 1 ||
      k_pe.shape(1) != 1 || topk_indices.shape(1) != 1 ||
      q_latent.shape(2) != q_pe.shape(2) || !topk_length_ok ||
      kv_latent.shape(2) != k_pe.shape(2) ||
      q_latent.shape(3) != kv_latent.shape(3) ||
      q_pe.shape(3) != k_pe.shape(3)) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] incompatible "
        << "shapes: " << q_latent.shape() << ", " << q_pe.shape() << ", "
        << kv_latent.shape() << ", " << k_pe.shape() << ", "
        << topk_indices.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (topk_indices.dtype() != uint32) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] topk_indices must "
        << "be uint32, got " << topk_indices.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (topk_length.has_value()) {
    const auto& lengths = *topk_length;
    const bool rank_ok = lengths.ndim() == 2 || lengths.ndim() == 3;
    const bool shape_ok = rank_ok && lengths.shape(0) == q_latent.shape(0) &&
        lengths.shape(lengths.ndim() - 1) == q_latent.shape(2) &&
        (lengths.ndim() == 2 || lengths.shape(1) == 1);
    if (!shape_ok) {
      std::ostringstream msg;
      msg << "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] teak_memory_bytes"] = None
    return metrics


async def _run_external_batch_test(
    client: ExternalAPIClient,
    prompts: list[str],
    max_tokens: int,
    batch_size: int,
) -> dict:
    """Run a concurrent-requests benchmark against an external endpoint.

    Mirrors _run_batch_test aggregation, with actual per-request token
    counts taken from each stream's usage payload.
    """
    wall_start = time.perf_counter()
    stats_list = await asyncio.gather(
        *[
            client.stream_chat_completion(
                messages=[{"role": "user", "content": prompt}],
                max_tokens=max_tokens,
                temperature=0.0,
            )
            for prompt in prompts
        ]
    )
    wall_end = time.perf_counter()

    total_gen_tokens = sum(s.completion_tokens for s in stats_list)
    prompt_tokens_per_request = [s.prompt_tokens for s in stats_list]
    total_prompt_tokens = sum(prompt_tokens_per_request)
    wall_time = wall_end - wall_start

    # Every aggregate below is derived from the per-request content
    # timestamps, so a single stream that never reported content poisons all
    # of them: its fallback timestamp sits at the end of the response and
    # drags max_first_token along with it.
    timing_observed = all(s.content_observed for s in stats_list)
    decode_observed = all(
        s.last_content_time > s.first_content_time for s in stats_list
    )

    max_first_token = max(s.first_content_time for s in stats_list)
    gen_window = wall_end - max_first_token

    avg_ttft_ms: float | None = None
    pp_tps: float | None = None
    tg_tps: float | None = None
    if timing_observed:
        total_ttft_s = sum(s.first_content_time - s.start_time for s in stats_list)
        avg_ttft_ms = round((total_ttft_s / batch_size) * 1000, 1)
        # pp TPS: total prompt tokens / time until ALL requests emit content
        prefill_window = max(max_first_token - wall_start, 1e-9)
        pp_tps = round(total_prompt_tokens / prefill_window, 1)
        # tg TPS needs a real decode span. wall_end is sampled after
        # asyncio.gather returns, so gen_window stays positive even when
        # every per-request timestamp collapsed onto the end of the
        # response, and the window alone cannot tell a genuine decode phase
        # from a single-chunk dump.
        if decode_observed and gen_window > 0:
            tg_tps = round(total_gen_tokens / gen_window, 1)

    return {
        "pp_tps": pp_tps,
        "tg_tps": tg_tps,
        "avg_ttft_ms": avg_ttft_ms,
        "e2e_latency_s": round(wall_time, 3),
        "total_gen_tokens": total_gen_tokens,
        "total_prompt_tokens": total_prompt_tokens,
        "prompt_tokens": round(total_prompt_tokens / batch_size),
        "prompt_tokens_min": min(prompt_tokens_per_request),
        "prompt_tokens_max": max(prompt_tokens_per_request),
        "batch_size": batch_size,
    }


OMLX_AI_API_URL = "https://omlx.ai/api/benchmarks"

# The leaderboard accepts model_name up to 150 characters.
_MAX_MODEL_NAME_LEN = 150


def _detect_quantization(model_path: str) -> str:
    """Detect model quantization from config.json or directory name.

    Fallback chain: config.json → directory name → "unknown"
    """
    config_path = Path(model_path) / "config.json"
    if config_path.exists():
        try:
            with open(config_path) as f:
                config = json.load(f)
            qconfig = config.get("quantization_config", {})
            bits = qconfig.get("bits")
            if bits is not None:
                return f"{bits}bit"
        except Exception:
            pass

    # Fallback: extract from directory name
    dirname = Path(model_path).name
    match = re.search(
        r"(2bit|3bit|4bit|6bit|8bit|fp16|bf16|MXFP4|NVFP4)", dirname, re.IGNORECASE
    )
    if match:
        return match.group(1).lower()

    return "unknown"


def _upload_model_name(model_id: str) -> str:
    """Model name to publish: exactly what oMLX shows and its copy button copies.

    Quantization and MLX suffixes used to be stripped herhf.mirror.placeholder",
                                    defaultValue: "https://hf-mirror.com  (empty = huggingface.co)",
                                    comment: "Placeholder for the HF mirror endpoint input"),
                mono: true
            )
            .frame(maxWidth: .infinity)
            .focused($mirrorFocused)
            .onSubmit { onSaveMirror() }
            Button(String(localized: "downloads.mirror.reset",
                          defaultValue: "Reset",
                          comment: "Button that clears the mirror endpoint back to the default")) {
                mirrorDraft = ""
                onResetMirror()
            }
            .buttonStyle(.omlx(.plain, size: .small))
            .disabled(mirrorBusy || (!mirrorIsCustom && mirrorDraft.isEmpty))
            Button(String(localized: "common.cancel",
                          defaultValue: "Cancel",
                          comment: "Generic cancel button")) {
                isEditingMirror = false
                mirrorDraft = ""
            }
            .buttonStyle(.omlx(.normal, size: .small))
            .disabled(mirrorBusy)
            Button(String(localized: "common.save",
                          defaultValue: "Save",
                          comment: "Generic save button")) { onSaveMirror() }
                .buttonStyle(.omlx(.primary, size: .small))
                .disabled(mirrorBusy)
        }
        .onAppear { mirrorFocused = true }
    }
}

// MARK: - Add from MS

/// Visual + behavioral parallel of AddFromHFSection for the ModelScope flow.
/// Keeps the two source forms structurally identical so users moving between
/// them aren't relearning the affordances — only labels + placeholders change.
private struct AddFromMSSection: View {
    @Binding var repoText: String
    let isStarting: Bool
    let mirrorHost: String
    let mirrorIsCustom: Bool
    @Binding var isEditingMirror: Bool
    @Binding var mirrorDraft: String
    let mirrorBusy: Bool
    let searchResults: [MSModelInfo]
    let searchLoading: Bool
    let searchDismissed: Bool
    let onSubmit: () -> Void
    let onSaveMirror: () -> Void
    let onResetMirror: () -> Void
    let onPickResult: (MSModelInfo) -> Void
    let onDismissSearch: () -> Void
    let onShowCard: (String) -> Void

    @Environment(\.omlxTheme) private var theme
    @FocusState private var mirrorFocused: Bool

    private var showsDropdown: Bool {
        !searchDismissed && (searchLoading || !searchResults.isEmpty)
    }

    var body: some View {
        SectionHeader(String(localized: "downloads.ms.section.title",
                              defaultValue: "Add Model from ModelScope",
                              comment: "Section heading above the ModelScope download form"))

        ListGroup {
            FreeRow(isLast: true) {
                VStack(alignment: .leading, spacing: 10) {
                    HStack(spacing: 8) {
                        TextInput(
                            text: $repoText,
                            placeholder: "mlx-community/Qwen2.5-7B-Instruct-4bit",
                            mono: true
                        )
                        .frame(maxWidth: .infinity)
                        .onSubmit(onSubmit)
                        if searchLoading {
                            ProgressView()
                                .controlSize(.small)
                                .padding(.trailing, 2)
                        }
                        Button {
                            onSubmit()
                        } label: {
                            Label(String(localized: "downloads.button.download",
                                         defaultValue: "Download",
                                         comment: "Primary button that starts downloading the entered repo"),
                                  systemImage: "icloud.and.arrow.down")
                                .labelStyle(.titleAndIcon)
                        }
                        .buttonStyle(.omlx(.primary))
                        .disabled(repode_haiku_model: this.globalSettings.claude_code.haiku_model,
                        }),
                    });
                    if (!response.ok) {
                        console.error('Failed to save Claude Code settings');
                    }
                } catch (err) {
                    console.error('Failed to save Claude Code settings:', err);
                }
            },

            _launchCmd(tool) {
                const raw = this.stats.cli_prefix || 'omlx';
                const cli = raw === 'omlx' ? raw : this.shellQuote(raw);
                return `${cli} launch ${tool}`;
            },

            get claudeCommand() {
                return this._launchCmd('claude');
            },

            get codexCommand() {
                return this._launchCmd('codex');
            },

            get codexAppCommand() {
                return this._launchCmd('codex_app');
            },

            get copilotCommand() {
                return this._launchCmd('copilot');
            },

            get opencodeCommand() {
                return this._launchCmd('opencode');
            },

            get openclawCommand() {
                const profile = this.globalSettings.integrations.openclaw_tools_profile || 'coding';
                return `${this._launchCmd('openclaw')} --tools-profile ${profile}`;
            },

            get hermesCommand() {
                return this._launchCmd('hermes');
            },

            get piCommand() {
                return this._launchCmd('pi');
            },

            get markitdownOcrModels() {
                return (this.models || []).filter((model) => {
                    const configType = String(model.config_model_type || '').toLowerCase();
                    return configType.includes('ocr');
                });
            },

            async saveIntegrationSettings() {
                try {
                    const response = await fetch('/admin/api/global-settings', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            integrations_copilot_model: this.globalSettings.integrations.copilot_model,
                            integrations_codex_model: this.globalSettings.integrations.codex_model,
                            integrations_opencode_model: this.globalSettings.integrations.opencode_model,
                            integrations_openclaw_model: this.globalSettings.integrations.openclaw_model,
                            integrations_hermes_model: this.globalSettings.integrations.hermes_model,
                            integrations_pi_model: this.globalSettings.integrations.pi_model,
                            integrations_openclaw_tools_profile: this.globalSettings.integrations.openclaw_tools_profile,
                            markitdown_enabled: this.globalSettings.integrations.markitdown_enabled,
                            markitdown_expose_model: this.globalSettings.integrations.markitdown_expose_model,
                            markitdown_max_file_size_mb: this.globalSettings.integrations.markitdown_max_file_size_mb,
                            markitdown_max_files_per_request: this.globalSettings.integrations.markitdown_max_files_per_request,
                            markitdown_pdf_processing_engine: this.globalSettings.integrations.markitdown_pdf_processing_engine,
                        }),
                    });
                    if (!response.ok) {
                        console.error('Failed to save integration settings');
                    }
                } catch (err) {
                    console.error('Failed to save integration settings:', err);
                }
            },

            async saveLanguage(lang) {
                try {
                    const response = await fetch('/admin/api/global-settings', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                  opk_length "
          << "with shape " << lengths.shape() << " expected [B, L] or "
          << "[B, 1, L].";
      throw std::invalid_argument(msg.str());
    }
    if (lengths.dtype() != uint32) {
      std::ostringstream msg;
      msg << "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] topk_length must "
          << "be uint32, got " << lengths.dtype() << ".";
      throw std::invalid_argument(msg.str());
    }
  }

  auto final_type =
      result_type(std::vector<array>{q_latent, q_pe, kv_latent, k_pe});
  if (final_type != float16 && final_type != bfloat16 && final_type != float32) {
    std::ostringstream msg;
    msg << "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] expected floating "
        << "inputs, got " << final_type << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  auto ql = astype(q_latent, final_type, stream);
  auto qp = astype(q_pe, final_type, stream);
  auto kv = astype(kv_latent, final_type, stream);
  auto kp = astype(k_pe, final_type, stream);

  std::vector<array> inputs = {ql, qp, kv, kp, topk_indices};
  if (topk_length.has_value()) {
    inputs.push_back(*topk_length);
  }
  if (GlmDsaSparseMlaAttentionPrimitive::unsupported(
          ql,
          qp,
          kv,
          kp,
          topk_indices,
          topk_length,
          topk_valid_prefix,
          causal_prefix_indices,
          causal_prefix_rows,
          causal,
          stream)) {
    throw std::invalid_argument(
        "[omlx_glm_kernels.glm_dsa_sparse_mla_attention] unsupported M3 GLM shape.");
  }

  Shape out_shape{ql.shape(0), ql.shape(1), ql.shape(2), kv.shape(3)};
  return array(
      std::move(out_shape),
      final_type,
      std::make_shared<GlmDsaSparseMlaAttentionPrimitive>(
          stream,
          scale,
          causal,
          topk_valid_prefix,
          causal_prefix_indices,
          topk_length.has_value(),
          causal_prefix_rows),
      std::move(inputs));
}

} // namespace omlx::glm_kernels


# ===== FILE: omlx/custom_kernels/minimax_m3/csrc/bindings.cpp =====

#include <nanobind/nanobind.h>
#include <nanobind/stl/variant.h>

#include "minimax_msa.h"

namespace nb = nanobind;
using namespace nb::literals;

NB_MODULE(_ext, m) {
  m.doc() = "Native MiniMax M3 kernels for oMLX";

  // ABI canary: when the extension is built with a nanobind whose ABI tag
  // differs from the one the mlx wheel was built with, the NB_DOMAIN is
  // isolated and every mx.array argument is rejected with "incompatible
  // function arguments" (issue #2139). fast.py calls this probe once at
  // import and disables the native symbols when it fails.
  m.def(
      "abi_probe",
      [](const mlx::core::array& a) {
        return static_cast<int64_t>(a.size());
      },
      "a"_a);

  m.def(
      "minimax_msa_topk",
      &omlx::minimax_m3_kernels::minimax_msa_topk,
      "idx_queries"_a,
      "idx_keys"_a,
      "q_start"_a,
      "scale"_a,
      "block_size"_a,
      "topk"_a,
      "init_blocks"_a,
      "local_blocks"_a,
      "stream"_a = nb::none());
}


# ===== FILE: omlx/custom_kernels/minimax_m3/csrc/minimax_msa.cpp =====

#include "minimax_msa.h"

#include <dlfcn.h>
#include <filesystem>
#include <limits>
#include <sstream>

#include "mlx/backend/common/utils.h"
#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/kernels/steel/gemm/params.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"
#include "mlx/utils.h"

namespace omlx::minimax_m3_kernels {

namespace {

using namespace mlx::core;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error(
          "Unable to get omlx_minimax_m3_kernels binary dir.");
    }
    return std::filesystem::path(info.dli_fname).parent_path().string();
  }();
  return binary_dir;
}

bool row_contiguous(const array& arr) {
  return arr.flags().row_contiguous && arr.strides(-1) == 1 &&
      arr.offset() == 0;
}

array ensure_row_contiguous(const array& e, which lost the one
    detail that distinguishes two builds of the same model on the leaderboard.
    The trailing path component is taken defensively — discovery registers ids
    as a single path component today, so this is a no-op for local runs.
    """
    name = model_id.rstrip("/").split("/")[-1]
    return name[:_MAX_MODEL_NAME_LEN]


def _sanitize_upload_error(resp: Any) -> str:
    """Extract a user-presentable error string from a failed upload response.

    Avoids dumping raw HTML bodies (e.g. Cloudflare's "Just a moment..."
    challenge interstitial) into the dashboard's red-x error column.
    Detects CF mitigation specifically so users get actionable context
    instead of a 5KB markup blob.

    Resolution order:
    1. Cloudflare challenge — header ``cf-mitigated: challenge`` is
       authoritative; a body sniff for "just a moment" / "cf-chl" covers
       edge transports that strip the header.
    2. JSON envelope — the omlx.ai API's normal error shape; extract
       ``error`` / ``detail`` / ``message`` if present, truncated.
    3. Plain-text body — short responses only; HTML-looking bodies are
       collapsed to a one-line "non-JSON response (N bytes)" hint.
    4. Fallback to the bare HTTP status code.
    """
    headers = getattr(resp, "headers", {}) or {}
    cf_mitigated = str(headers.get("cf-mitigated", "")).lower()
    body = getattr(resp, "text", "") or ""
    status = getattr(resp, "status_code", "?")

    body_head = body[:512].lower()
    if (
        cf_mitigated == "challenge"
        or "just a moment" in body_head
        or "cf-chl" in body_head
    ):
        return (
            f"Upload blocked by Cloudflare (HTTP {status}). "
            f"This is a server-side issue with omlx.ai — retry later or "
            f"report it to the maintainer."
        )

    try:
        data = resp.json()
        msg = data.get("error") or data.get("detail") or data.get("message")
        if msg:
            return str(msg)[:300]
    except Exception:
        pass

    text = body.strip()
    if "<" in text and ">" in text:
        return f"HTTP {status} — unexpected non-JSON response ({len(body)} bytes)"
    return text[:300] or f"HTTP {status}"


async def _upload_to_omlx_ai(run: BenchmarkRun, engine_pool: Any) -> None:
    """Upload benchmark results to omlx.ai community benchmarks.

    Sends each single-request result as a separate submission,
    grouped by submission_group. Upload failures don't affect
    the benchmark run status.
    """
    import requests

    from .._version import __version__
    from ..utils.hardware import (
        compute_owner_hash,
        get_chip_name,
        get_gpu_core_count,
        get_io_platform_uuid,
        get_os_version,
        get_total_memory_gb,
        parse_chip_info,
    )

    # Accelerated runs upload too. They carry their flags so the leaderboard
    # can mark and filter them, which is more useful than withholding the one
    # set of numbers people most want to see.
    run.upload_state["feature_flags"] = list(run.feature_flags)
    if run.feature_flags:
        logger.info(
            "Benchmark upload tagged with acceleration flags: "
            f"{[f['key'] for f in run.feature_flags]}"
        )

    run.upload_state["phase"] = "uploading"
    await _send_event(
        run,
        {
            "type": "progress",
            "phase": "upload",
            "message": "Uploading to community benchmarks...",
            "current": 0,
            "total": 0,
        },
    )

    # Collect hardware info
    chip_string = get_chip_name()
    chip_name, chip_variant = parse_chip_info(chip_string)
    memory_gb = round(get_total_memory_gb())
    gpu_cores = get_gpu_core_count()
    os_version = get_os_version()
    omlx_version = __version__

    # Compute owner_hash
    owner_hash_full = None
    owner_hash_display = None
    io_uuid = get_io_platform_uuid()
    if io_uuid:
        owner_hash_full = compute_owner_hash(io_uuid, chip_name, gpu_cores, memory_gb)
        # Display hash is without the verify character
        owner_hoText.isEmpty || isStarting)
                    }
                    if showsDropdown {
                        SearchDropdown(
                            results: searchResults,
                            isLoading: searchLoading,
                            onPick: onPickResult,
                            onDismiss: onDismissSearch,
                            onShowCard: onShowCard
                        )
                    }
                    if isEditingMirror {
                        mirrorEditor
                    } else {
                        mirrorSummary
                    }
                }
            }
        }
    }

    private var mirrorSummary: some View {
        HStack(spacing: 8) {
            Image(systemName: "globe")
                .font(.system(size: 11))
                .foregroundStyle(theme.textTertiary)
            Text(String(localized: "downloads.mirror.label",
                        defaultValue: "Mirror:",
                        comment: "Inline label preceding the mirror host on the Downloads screen"))
                .font(.omlxText(11))
                .foregroundStyle(theme.textTertiary)
            Text(mirrorHost)
                .font(.omlxMono(11))
                .foregroundStyle(theme.textSecondary)
            if mirrorIsCustom {
                Text(String(localized: "downloads.mirror.custom",
                            defaultValue: "custom",
                            comment: "Badge shown next to the mirror host when the user has configured a custom endpoint"))
                    .font(.omlxText(10, weight: .medium))
                    .foregroundStyle(theme.blueDot)
                    .padding(.horizontal, 5)
                    .padding(.vertical, 1)
                    .background(theme.blueDot.opacity(0.12))
                    .clipShape(Capsule())
            }
            Spacer(minLength: 8)
            Button(String(localized: "downloads.mirror.configure",
                          defaultValue: "Configure mirror…",
                          comment: "Button that opens the inline mirror editor")) {
                mirrorDraft = mirrorIsCustom ? mirrorHost : ""
                isEditingMirror = true
            }
            .buttonStyle(.omlx(.plain, size: .small))
            .disabled(mirrorBusy)
        }
    }

    private var mirrorEditor: some View {
        HStack(spacing: 8) {
            TextInput(
                text: $mirrorDraft,
                placeholder: String(localized: "downloads.ms.mirror.placeholder",
                                    defaultValue: "https://modelscope.cn  (empty = ModelScope default)",
                                    comment: "Placeholder for the ModelScope mirror endpoint input"),
                mono: true
            )
            .frame(maxWidth: .infinity)
            .focused($mirrorFocused)
            .onSubmit { onSaveMirror() }
            Button(String(localized: "downloads.mirror.reset",
                          defaultValue: "Reset",
                          comment: "Button that clears the mirror endpoint back to the default")) {
                mirrorDraft = ""
                onResetMirror()
            }
            .buttonStyle(.omlx(.plain, size: .small))
            .disabled(mirrorBusy || (!mirrorIsCustom && mirrorDraft.isEmpty))
            Button(String(localized: "common.cancel",
                          defaultValue: "Cancel",
                          comment: "Generic cancel button")) {
                isEditingMirror = false
                mirrorDraft = ""
            }
            .buttonStyle(.omlx(.normal, size: .small))
            .disabled(mirrorBusy)
            Button(String(localized: "common.save",
                          defaultValue: "Save",
                          comment: "Generic save button")) { onSaveMirror() }
                .buttonStyle(.omlx(.primary, size: .small))
                .disabled(mirrorBusy)
        }
        .onAppear { mirrorFocused = true }
    }
}

// MARK: - Search dropdown

private struct SearchDropdown: View {
    let res      body: JSON.stringify({ ui_language: lang })
                    });
                    if (response.ok) {
                        location.reload();
                    } else {
                        console.error('Failed to save language');
                    }
                } catch (e) {
                    console.error('Failed to save language:', e);
                }
            },

            async loadStats(includeAlltime = true) {
                try {
                    const params = new URLSearchParams();
                    if (this.selectedStatsModel) {
                        params.set('model', this.selectedStatsModel);
                    }
                    const url = '/admin/api/stats' + (params.toString() ? '?' + params : '');
                    const response = await fetch(url);
                    if (response.ok) {
                        const data = await response.json();
                        this.stats = { ...this.stats, ...data };
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    }

                    if (!includeAlltime) {
                        return;
                    }

                    // Load all-time stats
                    const alltimeParams = new URLSearchParams({ scope: 'alltime' });
                    if (this.selectedStatsModel) {
                        alltimeParams.set('model', this.selectedStatsModel);
                    }
                    const alltimeUrl = '/admin/api/stats?' + alltimeParams;
                    const alltimeResponse = await fetch(alltimeUrl);
                    if (alltimeResponse.ok) {
                        const alltimeData = await alltimeResponse.json();
                        this.alltimeStats = { ...this.alltimeStats, ...alltimeData };
                    }
                } catch (err) {
                    console.error('Failed to load stats:', err);
                }
            },

            async clearStats() {
                try {
                    await fetch('/admin/api/stats/clear', { method: 'POST' });
                    this.showClearStatsConfirm = false;
                    await this.loadStats();
                } catch (err) {
                    console.error('Failed to clear stats:', err);
                    this.showClearStatsConfirm = false;
                }
            },

            async clearAlltimeStats() {
                try {
                    await fetch('/admin/api/stats/clear-alltime', { method: 'POST' });
                    this.showClearAlltimeConfirm = false;
                    await this.loadStats();
                } catch (err) {
                    console.error('Failed to clear all-time stats:', err);
                    this.showClearAlltimeConfirm = false;
                }
            },

            async clearSsdCache() {
                try {
                    const resp = await fetch('/admin/api/ssd-cache/clear', { method: 'POST' });
                    if (!resp.ok) console.error('SSD cache clear failed:', resp.status);
                    this.showClearSsdCacheConfirm = false;
                    await this.loadStats();
                } catch (err) {
                    console.error('Failed to clear SSD cache:', err);
                    this.showClearSsdCacheConfirm = false;
                }
            },

            async clearHotCache() {
                try {
                    const resp = await fetch('/admin/api/hot-cache/clear', { method: 'POST' });
                    if (!resp.ok) console.error('Hot cache clear failed:', resp.status);
                    this.showClearHotCacheConfirm = false;
                    await this.loadStats();
                } catch (err) {
                    console.error('Failed to clear hot cache:', err);
                    this.showClearHotCacheConfirm = false;
                }
            },

            startStatsRefresh() {
                this.stopStatsRefresh();
                this.loadStats();
                this._sarr, Stream stream) {
  return contiguous(arr, false, stream);
}

class MinimaxMSATopKPrimitive : public Primitive {
 public:
  MinimaxMSATopKPrimitive(
      Stream stream,
      int q_start,
      float scale,
      int block_size,
      int topk,
      int init_blocks,
      int local_blocks)
      : Primitive(stream),
        q_start_(q_start),
        scale_(scale),
        block_size_(block_size),
        topk_(topk),
        init_blocks_(init_blocks),
        local_blocks_(local_blocks) {}

  static bool unsupported(
      const array& idx_queries,
      const array& idx_keys,
      int block_size,
      int topk,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (idx_queries.dtype() != idx_keys.dtype()) {
      return true;
    }
    if (idx_queries.dtype() != float32 && idx_queries.dtype() != float16 &&
        idx_queries.dtype() != bfloat16) {
      return true;
    }
    if (idx_queries.ndim() != 4 || idx_keys.ndim() != 4 ||
        idx_keys.shape(1) != 1) {
      return true;
    }
    if (!row_contiguous(idx_queries) || !row_contiguous(idx_keys)) {
      return true;
    }
    if (idx_queries.shape(0) != idx_keys.shape(0) ||
        idx_queries.shape(3) != idx_keys.shape(3)) {
      return true;
    }

    return block_size != 128 || topk != 16 || idx_queries.shape(3) != 128 ||
        idx_queries.shape(2) <= 0 || idx_keys.shape(2) <= 0;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("MinimaxMSATopKPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& q = inputs[0];
    auto& k = inputs[1];
    auto& out = outputs[0];

    constexpr int bm = 64;
    constexpr int bn = 128;
    constexpr int bk = 16;
    constexpr int wm = 2;
    constexpr int wn = 2;
    constexpr int topk_threads = 256;

    const int B = q.shape(0);
    const int H = q.shape(1);
    const int M = q.shape(2);
    const int N = k.shape(2);
    const int D = q.shape(3);
    const int num_blocks = (N + block_size_ - 1) / block_size_;
    const int tiles_m = (M + bm - 1) / bm;

    mlx::steel::GEMMParams params{
        /* const int M = */ M,
        /* const int N = */ N,
        /* const int K = */ D,
        /* const int lda = */ D,
        /* const int ldb = */ D,
        /* const int ldd = */ num_blocks,
        /* const int tiles_n = */ num_blocks,
        /* const int tiles_m = */ tiles_m,
        /* const int64_t batch_stride_a = */ int64_t(H) * M * D,
        /* const int64_t batch_stride_b = */ int64_t(N) * D,
        /* const int64_t batch_stride_d = */ int64_t(H) * M * num_blocks,
        /* const int swizzle_log = */ 0,
        /* const int gemm_k_iterations_aligned = */ D / bk,
        /* const int batch_ndim = */ 1};

    array block_scores({B, H, M, num_blocks}, float32, nullptr, {});
    block_scores.set_data(allocator::malloc(block_scores.nbytes()));
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.add_temporary(block_scores);

    out.set_data(allocator::malloc(out.nbytes()));

    std::string block_kernel_name;
    concatenate(
        block_kernel_name,
        "minimax_msa_block_scores_",
        type_to_name(q),
        "_bm",
        bm,
        "_bn",
        bn,
        "_bk",
        bk,
        "_wm",
        wm,
        "_wn",
        wn);

    auto lib = d.get_library("omlx_minimax_m3_kernels", current_binary_dir());
    auto block_kernel = d.get_kernel(block_kernel_name, lib);
    compute_encoder.set_compute_pipeline_state(block_kernel);
    compute_encoder.set_input_array(q, 0);
    compute_encoder.set_input_array(k, 1);
    compute_encoder.set_output_array(block_scores, 2);
    compute_encoder.set_bytes(params, 3);
    compute_encoder.set_bytes(H, 4);
    compute_encoder.set_bytes(q_start_, 5);
    compute_encoder.set_bytes(block_size_, 6);
    compute_encoder.set_bytes(scale_, 7);
    computeash_display = owner_hash_full[:-1]

    # Get model info
    entry = engine_pool.get_entry(run.request.model_id)
    model_path = entry.model_path if entry else ""
    quantization = _detect_quantization(model_path)
    model_name = _upload_model_name(run.request.model_id)

    # Generate submission group
    submission_group = str(uuid.uuid4())

    # Peak process memory for the run. ri_lifetime_max_phys_footprint is a
    # high-water mark since process start, so it only describes this benchmark
    # when the benchmark actually set a new maximum — a server that previously
    # held a larger model would otherwise report that older peak. Fall back to
    # the sampler's own maximum, which is scoped to the run.
    peak_footprint_gb = None
    lifetime_end = get_lifetime_max_phys_footprint()
    peak_bytes = 0
    if lifetime_end and lifetime_end > run.lifetime_footprint_at_start:
        peak_bytes = lifetime_end
    elif run.sampler is not None:
        peak_bytes = run.sampler.run_peak_footprint()
    if peak_bytes > 0:
        peak_footprint_gb = round(peak_bytes / (1024**3), 2)

    # Collect single results and batch results
    single_results = [r for r in run.results if r.get("test_type") == "single"]
    uploadable_single_results = [
        r for r in single_results if float(r.get("gen_tps", 0.0) or 0.0) > 0.0
    ]
    skipped_count = len(single_results) - len(uploadable_single_results)
    batch_results = [r for r in run.results if r.get("test_type") == "batch"]

    # Build batching_results from batch data
    batching_results = []
    pp1024_single = next((r for r in single_results if r.get("pp") == 1024), None)
    if (
        pp1024_single
        and float(pp1024_single.get("gen_tps", 0.0) or 0.0) > 0.0
        and batch_results
    ):
        baseline_tps = pp1024_single["gen_tps"]
        batching_results.append(
            {
                "batch_size": 1,
                "tg_tps": baseline_tps,
                "speedup": 1.0,
            }
        )
        for br in batch_results:
            speedup = round(br["tg_tps"] / baseline_tps, 2) if baseline_tps > 0 else 1.0
            batching_results.append(
                {
                    "batch_size": br["batch_size"],
                    "tg_tps": br["tg_tps"],
                    "speedup": speedup,
                }
            )

    success_count = 0
    failed_count = 0

    if skipped_count:
        logger.info(
            f"Benchmark upload skipped {skipped_count} result(s) without "
            f"measurable generation throughput"
        )

    for result in uploadable_single_results:
        context_length = result["pp"]
        peak_mem_gb = None
        if result.get("peak_memory_bytes") and result["peak_memory_bytes"] > 0:
            peak_mem_gb = round(result["peak_memory_bytes"] / (1024**3), 2)

        payload = {
            "chip_name": chip_name,
            "chip_variant": chip_variant,
            "memory_gb": memory_gb,
            "gpu_cores": gpu_cores,
            "omlx_version": omlx_version,
            "os_version": os_version,
            "model_name": model_name,
            "quantization": quantization,
            "context_length": context_length,
            "context_profile": run.request.context_profile.value,
            "pp_tps": result["processing_tps"],
            "tg_tps": result["gen_tps"],
            "ttft_ms": result.get("ttft_ms"),
            "peak_memory_gb": peak_mem_gb,
            "submission_group": submission_group,
            "peak_footprint_gb": peak_footprint_gb,
            "feature_flags": run.feature_flags,
            "model_settings": _with_benchmark_context(
                run.request.context_profile,
                run.model_settings_snapshot,
            ),
            # Per-row: each context length has its own load window. Stays None
            # when sampling was unavailable, so the site does not average
            # fabricated zeros in as measurements.
            "system_metrics": result.get("system_metrics"),
        }

        if owner_hash_full:
            payload["ults: [HFModelInfo]
    let isLoading: Bool
    let onPick: (HFModelInfo) -> Void
    let onDismiss: () -> Void
    /// Reveal a small `info.circle` action on the hovered row. Skipped
    /// from the always-visible button family because each dropdown row
    /// is itself a Button (`onPick`); a permanent trailing icon would
    /// crowd the dense row and confuse "did the user mean to pick this
    /// or open the card?". Finder-style hover reveal sidesteps both
    /// problems.
    let onShowCard: (String) -> Void

    @Environment(\.omlxTheme) private var theme
    @State private var hoveredId: String?

    /// Cap visible rows at 8 — anything more is noise and the user can keep
    /// typing to narrow further. The HF API returns up to `limit` items
    /// (20 by default in the VM), we just truncate the visible slice.
    private var visible: ArraySlice<HFModelInfo> { results.prefix(8) }

    var body: some View {
        VStack(spacing: 0) {
            if results.isEmpty && isLoading {
                HStack(spacing: 8) {
                    Text(String(localized: "downloads.search.loading",
                                defaultValue: "Searching…",
                                comment: "Placeholder shown inside the autocomplete dropdown while a search is in flight"))
                        .font(.omlxText(11))
                        .foregroundStyle(theme.textTertiary)
                    Spacer()
                }
                .padding(.horizontal, 12)
                .padding(.vertical, 8)
            } else {
                ForEach(Array(visible.enumerated()), id: \.element.repoId) { idx, m in
                    // Two distinct tap targets in a single HStack:
                    //   1. row Button (left) — selects this result for download
                    //   2. info Button (right, hover-only) — opens the model card
                    // On hover we also hide the downloads count so the icon
                    // slots into the trailing area cleanly instead of overlapping.
                    HStack(spacing: 0) {
                        Button {
                            onPick(m)
                        } label: {
                            row(model: m, isHovered: hoveredId == m.repoId)
                        }
                        .buttonStyle(.plain)
                        .frame(maxWidth: .infinity)
                        if hoveredId == m.repoId {
                            Button {
                                onShowCard(m.repoId)
                            } label: {
                                Image(systemName: "info.circle")
                                    .font(.system(size: 12))
                                    .foregroundStyle(theme.textSecondary)
                                    .padding(.horizontal, 12)
                                    .padding(.vertical, 6)
                                    .contentShape(Rectangle())
                            }
                            .buttonStyle(.plain)
                            .help(String(localized: "downloads.button.show_card",
                                         defaultValue: "View model card",
                                         comment: "Tooltip on the info button that opens a model's README sheet"))
                            .transition(.opacity)
                        }
                    }
                    .onHover { hovering in
                        withAnimation(.easeOut(duration: 0.1)) {
                            hoveredId = hovering ? m.repoId : nil
                        }
                    }
                    if idx < visible.count - 1 {
                        Divider().opacity(0.4)
                    }
                }
            }
        }
        .background(theme.groupBg)
        .overlay(
            RoundedRectangle(cornerRadius: theme.cornerRadius, style: .continuous)
                .strokeBorder(theme.groupBorder, lineWidth: 0.5)
        )
        .clipShape(RoundedRectangle(cornerRadius: theme.cornerRadius, style: .continuous))
        .onExitComtatsRefreshTimer = setInterval(() => {
                    this.loadStats(false);
                }, 500);
            },

            stopStatsRefresh() {
                if (this._statsRefreshTimer) {
                    clearInterval(this._statsRefreshTimer);
                    this._statsRefreshTimer = null;
                }
            },

            formatNumber(num) {
                if (num >= 1000000000) return (num / 1000000000).toFixed(1) + 'B';
                if (num >= 10000000) return (num / 1000000).toFixed(1) + 'M';
                return num.toLocaleString();
            },

            cacheObsCumulative(stats, selectedModel) {
                const entries = stats.runtime_cache?.models || [];
                if (entries.length === 0) return {};

                if (selectedModel) {
                    const entry = entries.find(m => m.id === selectedModel);
                    return entry?.cache_rates?.cumulative || {};
                }

                const sumKeys = ['prefix_hits', 'prefix_misses', 'evictions', 'ssd_hot_hits', 'ssd_disk_loads', 'ssd_saves', 'hot_cache_evictions', 'hot_cache_promotions'];
                let agg = {};

                for (const m of entries) {
                    const c = m.cache_rates?.cumulative;
                    if (!c || Object.keys(c).length === 0) continue;
                    for (const k of sumKeys) {
                        agg[k] = (agg[k] || 0) + (c[k] || 0);
                    }
                }

                const ph = agg.prefix_hits || 0;
                const pm = agg.prefix_misses || 0;
                const sh = agg.ssd_hot_hits || 0;
                const sd = agg.ssd_disk_loads || 0;
                agg.prefix_hit_rate = (ph + pm) > 0 ? ph / (ph + pm) : 0;
                agg.ssd_hot_rate = (sh + sd) > 0 ? sh / (sh + sd) : 0;

                return agg;
            },

            getStatFontClass(value) {
                if (value >= 1000000000) return 'text-2xl';
                if (value >= 1000000) return 'text-3xl';
                return 'text-5xl';
            },

            formatSizeBytes(bytes) {
                if (bytes >= 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024)).toFixed(1) + ' GB';
                if (bytes >= 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(0) + ' MB';
                return '0';
            },

            formatByteCount(bytes) {
                if (bytes == null || !Number.isFinite(bytes)) return '';
                if (bytes >= 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024)).toFixed(1) + ' GB';
                if (bytes >= 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
                if (bytes >= 1024) return (bytes / 1024).toFixed(1) + ' KB';
                return Math.max(0, Math.round(bytes)) + ' B';
            },

            formatTokenCount(n) {
                if (n >= 1000000) return (n / 1000000).toFixed(1) + 'M';
                if (n >= 1000) return (n / 1000).toFixed(1) + 'k';
                return String(n);
            },

            formatDFlashSessionStats(totals) {
                if (!totals || totals.requests <= 1) return '';

                const parts = [];
                if (totals.speculative_requests > 0) {
                    parts.push(
                        Math.round((totals.acceptance_ratio || 0) * 100) + '% ' +
                        window.t('status.active_models.dflash_draft_share'),
                        (totals.accepted_draft_tokens_per_cycle || 0).toFixed(2) + ' ' +
                        window.t('status.active_models.dflash_accepted_draft_per_cycle'),
                        (totals.tokens_per_cycle || 0).toFixed(2) + ' ' +
                        window.t('status.active_models.dflash_output_per_cycle'),
                        totals.speculative_requests + ' ' +
                        window.t('status.active_models.dflash_speculative_requests'),
                    );
                }
                if (totals.fallback_requests > 0) {
                    parts.push(
                        totals_encoder.set_bytes(num_blocks, 8);

    MTL::Size block_grid(num_blocks, tiles_m, B * H);
    MTL::Size block_group(wm * wn * 32, 1, 1);
    compute_encoder.dispatch_threadgroups(block_grid, block_group);

    auto topk_kernel =
        d.get_kernel("minimax_msa_topk_select_topk16_t256", lib);
    compute_encoder.set_compute_pipeline_state(topk_kernel);
    compute_encoder.set_input_array(block_scores, 0);
    compute_encoder.set_output_array(out, 1);
    const int rows = B * H * M;
    compute_encoder.set_bytes(rows, 2);
    compute_encoder.set_bytes(H, 3);
    compute_encoder.set_bytes(M, 4);
    compute_encoder.set_bytes(num_blocks, 5);
    compute_encoder.set_bytes(q_start_, 6);
    compute_encoder.set_bytes(block_size_, 7);
    compute_encoder.set_bytes(init_blocks_, 8);
    compute_encoder.set_bytes(local_blocks_, 9);

    MTL::Size topk_grid(rows, 1, 1);
    MTL::Size topk_group(topk_threads, 1, 1);
    compute_encoder.dispatch_threadgroups(topk_grid, topk_group);
  }

  DEFINE_NAME(OMLXMinimaxMSATopK)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs = static_cast<const MinimaxMSATopKPrimitive&>(other);
    return q_start_ == rhs.q_start_ && scale_ == rhs.scale_ &&
        block_size_ == rhs.block_size_ && topk_ == rhs.topk_ &&
        init_blocks_ == rhs.init_blocks_ && local_blocks_ == rhs.local_blocks_;
  }
  auto state() const {
    return std::make_tuple(
        q_start_, scale_, block_size_, topk_, init_blocks_, local_blocks_);
  }

 private:
  int q_start_;
  float scale_;
  int block_size_;
  int topk_;
  int init_blocks_;
  int local_blocks_;
};

} // namespace

array minimax_msa_topk(
    const array& idx_queries,
    const array& idx_keys,
    int q_start,
    float scale,
    int block_size,
    int topk,
    int init_blocks,
    int local_blocks,
    StreamOrDevice s) {
  if (idx_queries.ndim() != 4 || idx_keys.ndim() != 4) {
    std::ostringstream msg;
    msg << "[omlx_minimax_m3.minimax_msa_topk] expected rank-4 idx "
        << "query/key arrays, got " << idx_queries.shape() << " and "
        << idx_keys.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (idx_queries.shape(0) != idx_keys.shape(0) || idx_keys.shape(1) != 1 ||
      idx_queries.shape(3) != idx_keys.shape(3)) {
    std::ostringstream msg;
    msg << "[omlx_minimax_m3.minimax_msa_topk] incompatible idx query/key "
        << "shapes " << idx_queries.shape() << " and " << idx_keys.shape()
        << ".";
    throw std::invalid_argument(msg.str());
  }
  if (block_size <= 0 || topk <= 0 || init_blocks < 0 || local_blocks < 0) {
    throw std::invalid_argument(
        "[omlx_minimax_m3.minimax_msa_topk] block_size/topk must be "
        "positive and forced block counts must be non-negative.");
  }

  auto stream = to_stream(s);
  auto final_type = result_type(idx_queries, idx_keys);
  if (final_type != float32 && final_type != float16 && final_type != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_minimax_m3.minimax_msa_topk] expected floating idx "
        << "query/key arrays, got " << final_type << ".";
    throw std::invalid_argument(msg.str());
  }

  auto q = ensure_row_contiguous(astype(idx_queries, final_type, stream), stream);
  auto k = ensure_row_contiguous(astype(idx_keys, final_type, stream), stream);
  std::vector<array> inputs = {q, k};
  if (MinimaxMSATopKPrimitive::unsupported(q, k, block_size, topk, stream)) {
    throw std::invalid_argument(
        "[omlx_minimax_m3.minimax_msa_topk] unsupported MiniMax M3 MSA "
        "top-k shape.");
  }

  Shape out_shape{q.shape(0), q.shape(1), q.shape(2), topk};
  return array(
      std::move(out_shape),
      int32,
      std::make_shared<MinimaxMSATopKPrimitive>(
          stream,
          q_start,
          scale,
          block_size,
          topk,
          init_blocks,
          local_blocks),
      std::move(inputs));
}

} // namespace omlx::minimax_m3_kernels


# ===== FILE: omlx/custom_kernels/qwen35_prefill/csrc/bindings.cpp =====

#include <nanobind/nanobind.h>
#includeowner_hash"] = owner_hash_full

        # Attach batching_results only to the first submission (lowest context_length)
        if context_length == uploadable_single_results[0]["pp"] and batching_results:
            payload["batching_results"] = batching_results

        try:
            resp = await asyncio.to_thread(
                requests.post,
                OMLX_AI_API_URL,
                json=payload,
                timeout=15,
            )

            if resp.status_code == 201:
                data = resp.json()
                success_count += 1
                result_dict = {
                    "context_length": context_length,
                    "id": data.get("id"),
                    "url": data.get("url"),
                }
                run.upload_state["results"].append(result_dict)
                await _send_event(
                    run,
                    {
                        "type": "upload",
                        "data": result_dict,
                    },
                )
            elif resp.status_code == 409:
                data = resp.json()
                success_count += 1  # Duplicate is still ok
                result_dict = {
                    "context_length": context_length,
                    "id": data.get("existing_id"),
                    "url": data.get("existing_url"),
                    "duplicate": True,
                }
                run.upload_state["results"].append(result_dict)
                await _send_event(
                    run,
                    {
                        "type": "upload",
                        "data": result_dict,
                    },
                )
            else:
                failed_count += 1
                error_msg = _sanitize_upload_error(resp)
                result_dict = {
                    "context_length": context_length,
                    "error": error_msg,
                }
                run.upload_state["results"].append(result_dict)
                await _send_event(
                    run,
                    {
                        "type": "upload",
                        "data": result_dict,
                    },
                )
                # Surface the sanitized message to ops; the full body
                # (truncated) goes to debug so it can still be retrieved
                # from the log file if needed.
                logger.warning(
                    f"Benchmark upload failed for pp{context_length}: "
                    f"{resp.status_code} {error_msg}"
                )
                if (resp.text or "")[:1] not in ("{", "["):
                    logger.debug(
                        "Benchmark upload non-JSON body (truncated): %r",
                        (resp.text or "")[:500],
                    )

        except Exception as e:
            failed_count += 1
            result_dict = {
                "context_length": context_length,
                "error": str(e),
            }
            run.upload_state["results"].append(result_dict)
            await _send_event(
                run,
                {
                    "type": "upload",
                    "data": result_dict,
                },
            )
            logger.warning(f"Benchmark upload error for pp{context_length}: {e}")

    run.upload_state["phase"] = "done"
    run.upload_state["total"] = len(uploadable_single_results)
    run.upload_state["success_count"] = success_count
    run.upload_state["failed_count"] = failed_count
    run.upload_state["skipped_count"] = skipped_count
    run.upload_state["owner_hash"] = owner_hash_display
    await _send_event(
        run,
        {
            "type": "upload_done",
            "data": {
                "owner_hash": owner_hash_display,
                "total": len(uploadable_single_results),
                "success": success_count,
                "failed": failed_count,
                "skipped": skipped_count,
                # Also on the event so SSE-only consumers (the HTML dashboard) get
                # the flagmand(perform: onDismiss)
    }

    private func row(model m: HFModelInfo, isHovered: Bool) -> some View {
        HStack(spacing: 8) {
            Image(systemName: "cube.transparent")
                .font(.system(size: 11))
                .foregroundStyle(theme.textTertiary)
            VStack(alignment: .leading, spacing: 1) {
                Text(m.repoId)
                    .font(.omlxMono(12))
                    .foregroundStyle(theme.text)
                    .lineLimit(1)
                    .truncationMode(.middle)
                if let detail = secondaryLine(m) {
                    Text(detail)
                        .font(.omlxText(10.5))
                        .foregroundStyle(theme.textTertiary)
                        .lineLimit(1)
                }
            }
            Spacer(minLength: 6)
            // Hide the downloads count on hover so the trailing slot is
            // free for the info button (rendered as a sibling outside
            // this row Button so its tap doesn't fall through to onPick).
            if !isHovered, let downloads = m.downloads, downloads > 0 {
                Text(formatNumber(downloads))
                    .font(.omlxMono(10.5))
                    .foregroundStyle(theme.textTertiary)
                    .padding(.trailing, 12)
            }
        }
        .padding(.leading, 12)
        .padding(.vertical, 6)
        .contentShape(Rectangle())
    }

    private func secondaryLine(_ m: HFModelInfo) -> String? {
        var parts: [String] = []
        if let p = m.paramsFormatted, !p.isEmpty { parts.append(p) }
        if let s = m.sizeFormatted, !s.isEmpty { parts.append(s) }
        return parts.isEmpty ? nil : parts.joined(separator: " · ")
    }
}

// MARK: - Active downloads

private struct ActiveDownloadsSection: View {
    let tasks: [HFTaskDTO]
    let onCancel: (String) -> Void
    let onRemove: (String) -> Void

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        SectionHeader(
            String(localized: "downloads.active.title",
                   defaultValue: "Active Downloads",
                   comment: "Section heading for the list of in-progress downloads"),
            subtitle: tasks.isEmpty
                ? String(localized: "downloads.active.subtitle.empty",
                         defaultValue: "No active tasks",
                         comment: "Subtitle for Active Downloads when there are none")
                : String(localized: "downloads.active.subtitle.running",
                         defaultValue: "\(tasks.count) running",
                         comment: "Subtitle for Active Downloads; placeholder is the count of running tasks")
        )

        if !tasks.isEmpty {
            ListGroup {
                ForEach(Array(tasks.enumerated()), id: \.element.id) { idx, task in
                    FreeRow(isLast: idx == tasks.count - 1) {
                        VStack(alignment: .leading, spacing: 6) {
                            HStack(spacing: 8) {
                                Image(systemName: "icloud.and.arrow.down")
                                    .font(.system(size: 12))
                                    .foregroundStyle(theme.blueDot)
                                Text(task.repoId)
                                    .font(.omlxMono(12))
                                    .foregroundStyle(theme.text)
                                    .lineLimit(1)
                                    .truncationMode(.middle)
                                Spacer(minLength: 4)
                                Text(String(localized: "downloads.progress.bytes",
                                            defaultValue: "\(Int(task.progress))% · \(formatBytes(task.downloadedSize)) of \(formatBytes(task.totalSize))",
                                            comment: "Per-row progress line during downloads. Placeholders: percent, bytes downloaded, total bytes"))
                                    .font(.omlxMono(11))
                                    .foregroundStyle(theme.textSecondary)
.fallback_requests + ' ' +
                        window.t('status.active_models.dflash_fallback_requests'),
                    );
                }
                return window.t('status.active_models.dflash_session') + ': ' + parts.join(' · ');
            },

            formatDurationShort(seconds) {
                if (seconds == null || !Number.isFinite(seconds)) return '—';
                if (seconds < 1) return seconds.toFixed(1) + 's';
                if (seconds < 60) return Math.round(seconds) + 's';
                const minutes = Math.floor(seconds / 60);
                const rem = Math.round(seconds % 60);
                if (minutes < 60) return minutes + 'm ' + rem + 's';
                const hours = Math.floor(minutes / 60);
                return hours + 'h ' + (minutes % 60) + 'm';
            },

            formatActivityAge(seconds) {
                if (seconds == null || !Number.isFinite(seconds)) return '';
                return 'last token ' + this.formatDurationShort(seconds) + ' ago';
            },

            formatActivityMetadata(activity) {
                const parts = [];
                if (activity.input_count != null) parts.push(activity.input_count + ' inputs');
                if (activity.document_count != null) parts.push(activity.document_count + ' docs');
                if (activity.token_count != null) parts.push(this.formatTokenCount(activity.token_count) + ' tok');
                if (activity.text_length != null) parts.push(activity.text_length + ' chars');
                if (activity.chunk_count != null) parts.push(activity.chunk_count + ' chunks');
                if (activity.output_bytes != null) parts.push(this.formatByteCount(activity.output_bytes));
                if (activity.file_size_bytes != null && activity.file_size_bytes > 0) parts.push(this.formatByteCount(activity.file_size_bytes));
                return parts.join(' · ');
            },

            activityDotClass(seconds) {
                if (seconds == null || !Number.isFinite(seconds)) return 'bg-green-400 animate-pulse';
                if (seconds < 15) return 'bg-green-400 animate-pulse';
                if (seconds < 30) return 'bg-amber-400 animate-pulse';
                return 'bg-red-400';
            },

            get runtimeHotCachePercent() {
                const rc = this.stats.runtime_cache;
                if (!rc || !rc.hot_cache_max_bytes) return 0;
                return Math.min(100, (rc.hot_cache_size_bytes / rc.hot_cache_max_bytes) * 100);
            },

            get runtimeSsdCachePercent() {
                const rc = this.stats.runtime_cache;
                if (!rc || !rc.disk_max_bytes) return 0;
                return Math.min(100, (rc.total_size_bytes / rc.disk_max_bytes) * 100);
            },

            get activeModelsPressurePercent() {
                const mp = this.stats.active_models?.memory_pressure;
                if (!mp || !mp.hard_bytes) return 0;
                return Math.min(100, (mp.current_bytes / mp.hard_bytes) * 100);
            },

            get activeModelsSoftPercent() {
                const mp = this.stats.active_models?.memory_pressure;
                if (!mp || !mp.hard_bytes || !mp.soft_bytes) return 0;
                return Math.min(100, (mp.soft_bytes / mp.hard_bytes) * 100);
            },

            get activeModelsPressureBarColor() {
                const pct = this.activeModelsPressurePercent;
                if (pct >= 90) return '#ef4444';
                if (pct >= 80) return '#f97316';
                if (pct >= 70) return '#f59e0b';
                if (pct >= 60) return '#facc15';
                return '#22c55e';
            },

            get activeModelsPressureBarStyle() {
                return `width: ${this.activeModelsPressurePercent}%; height: 100%; display: block; background-color: ${this.activeModelsPressureBarColor};`;
            },

            get activeModelsSoftMarkerStyle() {
                return `left: ${this.activeModelsSoftPercent}%; width: 1px; background-color: rgba(64, 64, 64, 0. <nanobind/stl/variant.h>

#include "qwen35_prefill.h"

namespace nb = nanobind;
using namespace nb::literals;

NB_MODULE(_ext, m) {
  m.doc() = "Native Qwen3.5/3.6 prefill kernels for oMLX";

  // ABI canary: when the extension is built with a nanobind whose ABI tag
  // differs from the one the mlx wheel was built with, the NB_DOMAIN is
  // isolated and every mx.array argument is rejected with "incompatible
  // function arguments" (issue #2139). fast.py calls this probe once at
  // import and disables the native symbols when it fails.
  m.def(
      "abi_probe",
      [](const mlx::core::array& a) {
        return static_cast<int64_t>(a.size());
      },
      "a"_a);

  m.def(
      "is_nax_available",
      &omlx::qwen35_prefill_kernels::is_nax_available);
  m.def(
      "nax_qmm_kernels_built",
      &omlx::qwen35_prefill_kernels::nax_qmm_kernels_built);
  m.def(
      "nax_qmm_runtime_active",
      &omlx::qwen35_prefill_kernels::nax_qmm_runtime_active);

  m.def(
      "qwen35_fa256_attention",
      &omlx::qwen35_prefill_kernels::qwen35_fa256_attention,
      "q"_a,
      "k"_a,
      "v"_a,
      "scale"_a,
      "causal"_a = true,
      "q_block"_a = 32,
      "k_block"_a = 8,
      "dispatch_budget"_a = 0,
      "stream"_a = nb::none());
  // Capability probe for fast.py: older extensions reject the
  // dispatch_budget kwarg, so the wrapper only forwards it when present.
  m.attr("FA256_HAS_DISPATCH_BUDGET") = true;
  m.def(
      "qwen35_q2_affine_qmm_t",
      &omlx::qwen35_prefill_kernels::qwen35_q2_affine_qmm_t,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "biases"_a,
      "variant"_a = 8,
      "use_nax"_a = false,
      "nax_variant"_a = 0,
      "group_size"_a = 64,
      "stream"_a = nb::none());
  m.def(
      "qwen35_q4_affine_qmm_t",
      &omlx::qwen35_prefill_kernels::qwen35_q4_affine_qmm_t,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "biases"_a,
      "variant"_a = 8,
      "use_nax"_a = false,
      "nax_variant"_a = 0,
      "group_size"_a = 64,
      "stream"_a = nb::none());
  m.def(
      "qwen35_q5_affine_qmm_t",
      &omlx::qwen35_prefill_kernels::qwen35_q5_affine_qmm_t,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "biases"_a,
      "variant"_a = 8,
      "use_nax"_a = false,
      "nax_variant"_a = 0,
      "group_size"_a = 64,
      "stream"_a = nb::none());
  m.def(
      "qwen35_q6_affine_qmm_t",
      &omlx::qwen35_prefill_kernels::qwen35_q6_affine_qmm_t,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "biases"_a,
      "variant"_a = 8,
      "use_nax"_a = false,
      "nax_variant"_a = 0,
      "group_size"_a = 64,
      "stream"_a = nb::none());
  m.def(
      "qwen35_q8_affine_qmm_t",
      &omlx::qwen35_prefill_kernels::qwen35_q8_affine_qmm_t,
      "x"_a,
      "weight"_a,
      "scales"_a,
      "biases"_a,
      "variant"_a = 8,
      "use_nax"_a = false,
      "nax_variant"_a = 0,
      "group_size"_a = 64,
      "stream"_a = nb::none());
  m.def(
      "qwen35_moe_weighted_sum",
      &omlx::qwen35_prefill_kernels::qwen35_moe_weighted_sum,
      "x_sorted"_a,
      "inv_order"_a,
      "scores"_a,
      "stream"_a = nb::none());
}


# ===== FILE: omlx/custom_kernels/qwen35_prefill/csrc/qwen35_prefill.cpp =====

#include "qwen35_prefill.h"

#include <dlfcn.h>
#include <algorithm>
#include <filesystem>
#include <sstream>
#include <string>
#include <vector>

#include <atomic>

#include "mlx/backend/common/utils.h"
#include "mlx/backend/metal/device.h"
#include "mlx/backend/metal/kernels/steel/attn/params.h"
#include "mlx/backend/metal/metal.h"
#include "mlx/backend/metal/utils.h"
#include "mlx/ops.h"
#include "mlx/utils.h"

namespace omlx::qwen35_prefill_kernels {

namespace {

using namespace mlx::core;
using namespace mlx::steel;

std::string current_binary_dir() {
  static std::string binary_dir = []() {
    Dl_info info;
    if (!dladdr(reinterpret_cast<void*>(&current_binary_dir), &info)) {
      throw std::runtime_error("Unable to get omlx_qwen35_prefill binary dir.");
    }
    return std::filesystem::path(info.dli_fname).parents without polling /results.
                "feature_flags": run.feature_flags,
            },
        },
    )

    logger.info(
        f"Benchmark upload complete: {success_count}/"
        f"{len(uploadable_single_results)} succeeded, skipped={skipped_count}"
    )


async def run_benchmark(run: BenchmarkRun, engine_pool: Any) -> None:
    """Execute a complete benchmark run.

    Phases:
    1. Unload all loaded models
    2. Load the target model
    3. Run single request tests
    4. Run batch tests
    5. Unload the benchmark model
    """
    request = run.request
    if request.external is not None:
        await _run_external_benchmark(run)
        return
    total_tests = len(request.prompt_lengths) + len(request.batch_sizes)
    current_test = 0
    overall_start = time.perf_counter()

    # Throughput measurements must not be skewed by the memory-guard
    # throttle shrinking chunks; pin speed priority for the run.
    previous_speed_priority = _pin_speed_priority(engine_pool)

    try:
        run.model_settings_snapshot = _with_benchmark_context(
            request.context_profile,
            None,
        )
        # Snapshot experimental flags at run start. Settings can change mid-run,
        # and the produced numbers are tied to whatever was active when
        # generation actually ran.
        model_settings = None
        sm = getattr(engine_pool, "_settings_manager", None)
        if sm is not None:
            try:
                model_settings = sm.get_settings(request.model_id)
                run.experimental_features.extend(
                    _detect_experimental_features(model_settings)
                )
                run.feature_flags = _derive_feature_flags(model_settings)
                run.model_settings_snapshot = _with_benchmark_context(
                    request.context_profile,
                    _filter_uploaded_settings(model_settings),
                )
            except Exception as e:
                logger.warning(
                    f"Benchmark: failed to read experimental flags for "
                    f"{request.model_id}: {e}"
                )

        # Phase 1: Unload all loaded models
        loaded_ids = engine_pool.get_loaded_model_ids()
        if loaded_ids:
            await _send_event(
                run,
                {
                    "type": "progress",
                    "phase": "unload",
                    "message": f"Unloading {len(loaded_ids)} model(s)...",
                    "current": 0,
                    "total": total_tests,
                },
            )
            for model_id in loaded_ids:
                try:
                    await engine_pool._unload_engine(model_id)
                    logger.info(f"Benchmark: unloaded {model_id}")
                except Exception as e:
                    logger.warning(f"Benchmark: failed to unload {model_id}: {e}")

        # Phase 2: Load the target model
        await _send_event(
            run,
            {
                "type": "progress",
                "phase": "load",
                "message": f"Loading {request.model_id}...",
                "current": 0,
                "total": total_tests,
            },
        )
        # VLM MTP requires VLMBatchedEngine (which has set_vlm_mtp_drafter),
        # so don't force LM-only loading when VLM MTP is enabled.
        vlm_mtp_active = (
            model_settings is not None
            and getattr(model_settings, "vlm_mtp_enabled", False)
            and getattr(model_settings, "vlm_mtp_draft_model", None)
        )
        force_lm = True if request.force_lm_engine else not vlm_mtp_active
        engine = await engine_pool.get_engine(
            request.model_id,
            force_lm=force_lm,
        )
        logger.info(f"Benchmark: loaded {request.model_id}")

        # Generate prompts for all needed lengths
        tokenizer = engine.tokenizer
        prompts: dict[int, list[int]] = {}
        for pp_len in request.prompt_lengths:
            prompts[pp_len] = _generate_prompt(
                tokenizer                                Button {
                                    if task.statusEnum == .pending || task.statusEnum == .downloading {
                                        onCancel(task.taskId)
                                    } else {
                                        onRemove(task.taskId)
                                    }
                                } label: {
                                    Image(systemName: "xmark")
                                        .font(.system(size: 11))
                                }
                                .buttonStyle(.omlx(.plain, size: .small))
                                .help(String(localized: "downloads.cancel.help",
                                             defaultValue: "Cancel",
                                             comment: "Tooltip on the X button that cancels or removes a download task"))
                            }
                            ProgressBar(progress: task.progress / 100, colors: [Color(rgb24: 0x0A84FF), Color(rgb24: 0x5E5CE6)])
                            HStack(spacing: 12) {
                                StatusChip(task: task)
                                if !task.error.isEmpty {
                                    Text(task.error)
                                        .font(.omlxMono(10.5))
                                        .foregroundStyle(theme.redDot)
                                        .lineLimit(2)
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

private struct StatusChip: View {
    let task: HFTaskDTO
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        let cfg: (Color, String) = {
            switch task.statusEnum {
            case .downloading: return (theme.blueDot,
                                       String(localized: "downloads.status.downloading",
                                              defaultValue: "Downloading",
                                              comment: "Status chip label while a download is actively transferring bytes"))
            case .pending:     return (theme.amberDot,
                                       String(localized: "downloads.status.queued",
                                              defaultValue: "Queued",
                                              comment: "Status chip label for a download waiting to start"))
            case .completed:   return (theme.greenDot,
                                       String(localized: "downloads.status.completed",
                                              defaultValue: "Completed",
                                              comment: "Status chip label for a finished download"))
            case .failed:      return (theme.redDot,
                                       String(localized: "downloads.status.failed",
                                              defaultValue: "Failed",
                                              comment: "Status chip label for a download that errored out"))
            case .cancelled:   return (theme.textTertiary,
                                       String(localized: "downloads.status.cancelled",
                                              defaultValue: "Cancelled",
                                              comment: "Status chip label for a download cancelled by the user"))
            case .paused:      return (theme.amberDot,
                                       String(localized: "downloads.status.paused",
                                              defaultValue: "Paused",
                                              comment: "Status chip label for a paused download"))
            case .none:        return (theme.textTertiary, task.status.capitalized)
            }
        }()
        StatusPill(status: .custom(color: cfg.0, label: cfg.1, fillBg: true))
    }
}

// MARK: - Completed / Failed tasks

private struct CompletedTasksSection: View {
    let tasks: [HFTaskDTO]
    let onRetry: (Str6);`;
            },

            activeModelsPressureLabel() {
                const mp = this.stats.active_models?.memory_pressure;
                if (!mp || !mp.enabled || !mp.hard_bytes) {
                    return window.t('status.active_models.enforcer_disabled');
                }
                return `${this.formatSizeBytes(mp.current_bytes)} / ${this.formatSizeBytes(mp.soft_bytes)} soft / ${this.formatSizeBytes(mp.hard_bytes)} hard`;
            },

            modelSizeLabel(model) {
                if (!model) return '-';
                const estimated = model.estimated_size_formatted || '-';
                if (model.is_loading) {
                    return estimated;
                }
                // actual_size is a rough phys_footprint delta captured at load
                // time and can include neighboring KV growth — mark with ~obs
                // so it doesn't read as exact.
                const actual = model.actual_size_formatted;
                if (!actual) {
                    return estimated;
                }
                if (!estimated || estimated === actual) {
                    return `~${actual} obs`;
                }
                return `~${actual} obs / ${estimated} est`;
            },

            copyToClipboard(text) {
                if (navigator.clipboard && window.isSecureContext) {
                    navigator.clipboard.writeText(text).catch(() => {
                        this._copyFallback(text);
                    });
                } else {
                    this._copyFallback(text);
                }
            },

            _copyFallback(text) {
                const textarea = document.createElement('textarea');
                textarea.value = text;
                textarea.style.position = 'fixed';
                textarea.style.opacity = '0';
                document.body.appendChild(textarea);
                textarea.select();
                try {
                    document.execCommand('copy');
                } catch (err) {
                    console.error('Failed to copy:', err);
                }
                document.body.removeChild(textarea);
            },

            async logout() {
                try {
                    await fetch('/admin/api/logout', { method: 'POST' });
                } catch (err) {
                    console.error('Logout error:', err);
                } finally {
                    window.location.href = '/admin';
                }
            },

            // Shared external endpoint settings (both bench tabs)
            saveExternalEndpoint() {
                localStorage.setItem('omlx_bench_external_base_url', this.externalBaseUrl.trim());
                localStorage.setItem('omlx_bench_external_api_key', this.externalApiKey);
                localStorage.setItem('omlx_bench_external_model', this.externalModel.trim());
            },

            externalConfigValid() {
                return !!(this.externalBaseUrl.trim() && this.externalModel.trim());
            },

            externalRequestBody() {
                return {
                    base_url: this.externalBaseUrl.trim(),
                    api_key: this.externalApiKey,
                    model: this.externalModel.trim(),
                };
            },

            parseAccuracyExtraBody() {
                const raw = this.accExternalExtraBody.trim();
                if (!raw) return {};

                let value;
                try {
                    value = JSON.parse(raw);
                } catch (_) {
                    throw new Error(window.t('js.error.external_extra_body_invalid_json'));
                }
                if (value === null || Array.isArray(value) || typeof value !== 'object') {
                    throw new Error(window.t('js.error.external_extra_body_object_required'));
                }

                const protectedFields = new Set([
                    'model', 'messages', 'stream', 'stream_options',
                    'max_tokens', 'temperature', 'api_key', 'authorization',
_path().string();
  }();
  return binary_dir;
}

bool last_dim_contiguous(const array& arr) {
  return arr.strides(-1) == 1;
}

bool row_contiguous(const array& arr) {
  return arr.flags().row_contiguous && arr.strides(-1) == 1;
}

std::string qwen_type_name(Dtype dtype) {
  if (dtype == float16) {
    return "float16_t";
  }
  if (dtype == bfloat16) {
    return "bfloat16_t";
  }
  std::ostringstream msg;
  msg << "Unsupported Qwen prefill kernel dtype: " << dtype << ".";
  throw std::invalid_argument(msg.str());
}

struct QwenQAffineVariant {
  int bm;
  int bk;
  int bn;
};

struct QwenQAffineNaxVariant {
  int bm;
  int bk;
  int bn;
  int wm;
  int wn;
};

bool qwen_q_affine_bits_supported(int bits) {
  return bits == 2 || bits == 4 || bits == 5 || bits == 6 || bits == 8;
}

bool qwen_q_affine_packed_shape_matches(int packed_dim, int K, int bits) {
  return K > 0 && packed_dim > 0 &&
      static_cast<int64_t>(packed_dim) * 32 == static_cast<int64_t>(K) * bits;
}

constexpr const char* kNaxMetallibName = "omlx_qwen35_prefill_kernels_nax";

// Set to false once loading the NAX metallib (or one of its pipelines) fails
// so every later call degrades to the classic kernels without re-probing.
std::atomic<bool> nax_qmm_runtime_ok{true};

QwenQAffineVariant qwen_q_affine_variant(int variant) {
  switch (variant) {
    case 0:
      return {/* bm = */ 32, /* bk = */ 32, /* bn = */ 32};
    case 1:
      return {/* bm = */ 32, /* bk = */ 64, /* bn = */ 32};
    case 2:
      return {/* bm = */ 32, /* bk = */ 64, /* bn = */ 64};
    case 3:
      return {/* bm = */ 64, /* bk = */ 64, /* bn = */ 64};
    case 4:
      return {/* bm = */ 16, /* bk = */ 64, /* bn = */ 64};
    case 5:
      return {/* bm = */ 64, /* bk = */ 64, /* bn = */ 128};
    case 6:
      return {/* bm = */ 128, /* bk = */ 64, /* bn = */ 64};
    case 7:
      return {/* bm = */ 128, /* bk = */ 64, /* bn = */ 32};
    case 8:
      return {/* bm = */ 64, /* bk = */ 32, /* bn = */ 64};
    case 9:
      return {/* bm = */ 128, /* bk = */ 32, /* bn = */ 64};
    default: {
      std::ostringstream msg;
      msg << "Unsupported Qwen affine qmm variant " << variant << ".";
      throw std::invalid_argument(msg.str());
    }
  }
}

// Must stay in sync with the instantiations in qwen35_qmm_nax.metal.
// Variant 0 matches the tile MLX ships for affine_qmm_t_nax. BK stays at or
// below the group size (64): QuantizedBlockLoader rejects larger columns.
QwenQAffineNaxVariant qwen_q_affine_nax_variant(int variant) {
  switch (variant) {
    case 0:
      return {/* bm = */ 64, /* bk = */ 64, /* bn = */ 64, 2, 2};
    case 1:
      return {/* bm = */ 32, /* bk = */ 64, /* bn = */ 64, 2, 2};
    case 2:
      return {/* bm = */ 128, /* bk = */ 64, /* bn = */ 64, 2, 2};
    case 3:
      return {/* bm = */ 64, /* bk = */ 64, /* bn = */ 128, 2, 2};
    case 4:
      return {/* bm = */ 64, /* bk = */ 32, /* bn = */ 64, 2, 2};
    case 5:
      return {/* bm = */ 64, /* bk = */ 64, /* bn = */ 64, 4, 1};
    case 6:
      return {/* bm = */ 64, /* bk = */ 64, /* bn = */ 64, 1, 4};
    default: {
      std::ostringstream msg;
      msg << "Unsupported Qwen affine qmm NAX variant " << variant << ".";
      throw std::invalid_argument(msg.str());
    }
  }
}

class Qwen35Fa256AttentionPrimitive : public Primitive {
 public:
  Qwen35Fa256AttentionPrimitive(
      Stream stream,
      float scale,
      bool causal,
      int q_block,
      int k_block,
      int64_t dispatch_budget)
      : Primitive(stream),
        scale_(scale),
        causal_(causal),
        q_block_(q_block),
        k_block_(k_block),
        dispatch_budget_(dispatch_budget) {}

  static bool unsupported(
      const array& q,
      const array& k,
      const array& v,
      bool causal,
      int q_block,
      int k_block,
      Stream s) {
    if (s.device == Device::cpu || !causal) {
      return true;
    }
    if (q.dtype() != k.dtype() || q.dtype() != v.dtype()) {
      return true;
    }
    if (q.dtype() != float16 && q.dtype() != bfloat16) {
      return true;
    }
    if (q.ndim() != ,
                pp_len,
                request.context_profile,
            )

        # Ensure pp1024 prompt exists for batch tests
        if request.batch_sizes and 1024 not in prompts:
            prompts[1024] = _generate_prompt(
                tokenizer,
                1024,
                request.context_profile,
            )

        # Warmup: run a short request to trigger JIT compilation,
        # Metal shader compilation, and KV cache initialization.
        # Without this, the first real benchmark test absorbs all
        # one-time overhead and shows artificially low pp TPS.
        await _send_event(
            run,
            {
                "type": "progress",
                "phase": "warmup",
                "message": "Warming up (JIT compile)...",
                "current": 0,
                "total": total_tests,
            },
        )
        warmup_prompt = _generate_prompt(tokenizer, 32, request.context_profile)
        warmup_max_tokens = (
            request.generation_length
            if getattr(engine, "is_diffusion_model", False)
            else 8
        )
        async for _ in engine.stream_generate(
            prompt=warmup_prompt, max_tokens=warmup_max_tokens, temperature=0.0
        ):
            pass
        logger.info("Benchmark: warmup complete")

        # Start host sampling after warmup: Metal shader and JIT compilation
        # would otherwise be folded into the CPU aggregates.
        run.lifetime_footprint_at_start = get_lifetime_max_phys_footprint()
        try:
            run.sampler = SystemSampler()
            run.sampler.start()
        except Exception as e:  # noqa: BLE001
            logger.warning(f"Benchmark: host sampling unavailable: {e}")
            run.sampler = None

        # Phase 3: Single request tests
        single_pp1024_gen_tps = None

        for pp_len in request.prompt_lengths:
            current_test += 1
            await _send_event(
                run,
                {
                    "type": "progress",
                    "phase": "single",
                    "message": f"Single: pp{pp_len}/tg{request.generation_length}",
                    "current": current_test,
                    "total": total_tests,
                },
            )

            # time.monotonic only — the test internals use perf_counter, and
            # the two clocks have different epochs.
            window_start = time.monotonic()
            metrics = await _run_single_test(
                engine=engine,
                prompt=prompts[pp_len],
                max_tokens=request.generation_length,
                pp_len=pp_len,
            )
            metrics["system_metrics"] = _sample_window(run, window_start)

            result = {
                "test_type": "single",
                "pp": pp_len,
                "tg": request.generation_length,
                **metrics,
            }
            run.results.append(result)

            await _send_event(run, {"type": "result", "data": result})

            # Store pp1024 gen_tps for speedup calculation
            if pp_len == 1024:
                single_pp1024_gen_tps = metrics["gen_tps"]

        # Phase 4: Batch tests
        # Each request has a unique UUID prefix (no cache hits)
        max_batch = max(request.batch_sizes) if request.batch_sizes else 0
        batch_prompts = [
            _generate_prompt(tokenizer, 1024, request.context_profile)
            for _ in range(max_batch)
        ]

        # Skip batch tests for engines without scheduler core (e.g. VLM/Diffusion)
        batch_core = _get_batch_benchmark_core(engine)
        if request.batch_sizes and batch_core is None:
            logger.info(
                "Batch test skipped: engine does not support concurrent batching"
            )
            current_test += len(request.batch_sizes)

        for batch_size in request.batch_sizes if batch_core is not None else []:
            current_test += 1
            await _send_event(
                run,
                {
                    "type": "progreing) -> Void
    let onRemove: (String) -> Void
    /// Open the model-card sheet for a row. Source is resolved by the VM
    /// from the active downloader tab.
    let onShowCard: (String) -> Void

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        if tasks.isEmpty { EmptyView() } else {
            SectionHeader(String(localized: "downloads.recent.title",
                                  defaultValue: "Recent Tasks",
                                  comment: "Section heading for recently completed or failed downloads"),
                          subtitle: String(localized: "downloads.recent.subtitle",
                                           defaultValue: "Recent: \(tasks.count)",
                                           comment: "Subtitle for Recent Tasks; placeholder is the count of recent terminal tasks"))
            ListGroup {
                ForEach(Array(tasks.enumerated()), id: \.element.id) { idx, task in
                    FreeRow(isLast: idx == tasks.count - 1) {
                        HStack(spacing: 8) {
                            StatusChip(task: task)
                            Text(task.repoId)
                                .font(.omlxMono(12))
                                .foregroundStyle(theme.text)
                                .lineLimit(1)
                                .truncationMode(.middle)
                            Spacer(minLength: 4)
                            if task.statusEnum == .failed || task.statusEnum == .cancelled {
                                Button(String(localized: "downloads.button.retry",
                                              defaultValue: "Retry",
                                              comment: "Button label that re-runs a failed or cancelled download")) { onRetry(task.taskId) }
                                    .buttonStyle(.omlx(.normal, size: .small))
                            }
                            Button {
                                onShowCard(task.repoId)
                            } label: {
                                Image(systemName: "info.circle")
                                    .font(.system(size: 11))
                            }
                            .buttonStyle(.omlx(.plain, size: .small))
                            .help(String(localized: "downloads.button.show_card",
                                         defaultValue: "View model card",
                                         comment: "Tooltip on the info button that opens a model's README sheet"))
                            Button {
                                onRemove(task.taskId)
                            } label: {
                                Image(systemName: "trash")
                                    .font(.system(size: 11))
                            }
                            .buttonStyle(.omlx(.plain, size: .small))
                        }
                    }
                }
            }
        }
    }
}

// MARK: - Suggested

private struct SuggestedSection: View {
    let models: [HFModelInfo]
    @Binding var sort: SuggestedSort
    let isLoading: Bool
    let onGet: (String) -> Void
    let onRefresh: () -> Void
    /// Open the model-card sheet for a row. Same intent as the equivalent
    /// callback on CompletedTasksSection.
    let onShowCard: (String) -> Void

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        SectionHeader(String(localized: "downloads.suggested.title",
                              defaultValue: "Suggested Models",
                              comment: "Section heading for the recommended-models section"),
                      subtitle: hint) {
            HStack(spacing: 6) {
                Popup(
                    selection: $sort,
                    width: 170,
                    options: SuggestedSort.allCases.map { ($0, $0.label) }
                )
                Button {
                    onRefresh()
                } label: {
                    Image(systemName: "arrow.clockwise")
                          ]);
                const blocked = Object.keys(value).filter(
                    key => protectedFields.has(key.toLowerCase())
                );
                if (blocked.length > 0) {
                    throw new Error(
                        window.t('js.error.external_extra_body_protected')
                            .replace('{fields}', blocked.sort().join(', '))
                    );
                }
                return value;
            },

            accuracyExternalRequestBody() {
                const body = this.externalRequestBody();
                const extraBody = this.parseAccuracyExtraBody();
                if (Object.keys(extraBody).length > 0) body.extra_body = extraBody;
                return body;
            },

            // Benchmark functions
            async startBenchmark() {
                if (this.benchExternalEnabled) {
                    if (!this.externalConfigValid()) {
                        this.benchError = window.t('js.error.external_endpoint_required');
                        return;
                    }
                } else if (!this.benchModelId) {
                    return;
                }

                // Collect selected prompt lengths
                const promptLengths = Object.entries(this.benchPromptLengths)
                    .filter(([_, v]) => v)
                    .map(([k, _]) => parseInt(k));

                if (promptLengths.length === 0) {
                    this.benchError = window.t('js.error.select_prompt_length');
                    return;
                }

                // Collect selected batch sizes
                const batchSizes = Object.entries(this.benchBatchSizes)
                    .filter(([_, v]) => v)
                    .map(([k, _]) => parseInt(k));

                // Load device info if not loaded yet
                if (!this.benchDeviceInfo) {
                    this.loadBenchDeviceInfo();
                }

                // Reset state
                this.benchRunning = true;
                this.benchProgress = null;
                this.benchSingleResults = [];
                this.benchBatchResults = [];
                this.benchError = '';
                this.benchBenchId = null;
                this.benchUploadResults = [];
                this.benchUploadDone = null;
                this.benchUploading = false;
                this.benchUploadSkipped = null;
                this.benchUploadFlags = [];
                this.benchRunExternal = this.benchExternalEnabled
                    ? { base_url: this.externalBaseUrl.trim(), model: this.externalModel.trim() }
                    : null;

                try {
                    const response = await fetch('/admin/api/bench/start', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            model_id: this.benchExternalEnabled ? this.externalModel.trim() : this.benchModelId,
                            context_profile: this.benchContextProfile,
                            prompt_lengths: promptLengths,
                            generation_length: 128,
                            batch_sizes: batchSizes,
                            force_lm_engine: this.benchExternalEnabled ? false : this.benchForceLmEngine,
                            external: this.benchExternalEnabled ? this.externalRequestBody() : null,
                        }),
                    });

                    if (response.status === 401) {
                        window.location.href = '/admin';
                        return;
                    }

                    if (!response.ok) {
                        const data = await response.json();
                        this.benchError = data.detail || window.t('js.error.start_benchmark_failed');
                        this.benchRunning = false;
                        return;
                    }

                    const data = await response.json();
                  4 || k.ndim() != 4 || v.ndim() != 4) {
      return true;
    }
    if (!last_dim_contiguous(q) || !last_dim_contiguous(k) ||
        !last_dim_contiguous(v)) {
      return true;
    }
    if (!((q_block == 16 || q_block == 32) &&
          (k_block == 8 || k_block == 16))) {
      return true;
    }
    if (q.shape(0) != k.shape(0) || q.shape(0) != v.shape(0) ||
        k.shape(0) != v.shape(0) || q.shape(1) % k.shape(1) != 0 ||
        k.shape(1) != v.shape(1) || k.shape(2) != v.shape(2) ||
        q.shape(2) > k.shape(2) || q.shape(2) <= 1 ||
        q.shape(3) != k.shape(3) || q.shape(3) != v.shape(3) ||
        q.shape(3) != 256) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("Qwen35Fa256AttentionPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);

    const auto& q = inputs[0];
    const auto& k = inputs[1];
    const auto& v = inputs[2];
    auto& o = outputs[0];

    const int bq = q_block_;
    const int bk = k_block_;
    const int wm = bq == 16 ? 2 : 4;
    constexpr int wn = 1;
    const int bd = q.shape(-1);

    const int B = q.shape(0);
    const int H = q.shape(1);
    const int qL = q.shape(2);
    const int kL = k.shape(2);
    const int gqa_factor = q.shape(1) / k.shape(1);

    const bool align_Q = (qL % bq) == 0;
    const bool align_K = (kL % bk) == 0;
    const bool has_mask = false;
    const bool has_sinks = false;
    const bool has_block_mask = false;
    const bool has_block_token_mask = false;
    const bool has_block_indices = false;
    const bool do_causal = causal_;

    metal::MTLFCList func_consts = {
        {&align_Q, MTL::DataType::DataTypeBool, 200},
        {&align_K, MTL::DataType::DataTypeBool, 201},
        {&has_mask, MTL::DataType::DataTypeBool, 300},
        {&do_causal, MTL::DataType::DataTypeBool, 301},
        {&has_sinks, MTL::DataType::DataTypeBool, 302},
        {&has_block_mask, MTL::DataType::DataTypeBool, 303},
        {&has_block_token_mask, MTL::DataType::DataTypeBool, 304},
        {&has_block_indices, MTL::DataType::DataTypeBool, 305}};

    std::string base_name;
    concatenate(
        base_name,
        "omlx_qwen35_fa256_attention_",
        type_to_name(q),
        "_bq",
        bq,
        "_bk",
        bk,
        "_bd",
        bd,
        "_wm",
        wm,
        "_wn",
        wn,
        "_mask",
        type_to_name(q));

    std::string hash_name;
    concatenate(
        hash_name,
        "omlx_qwen35_fa256_",
        type_to_name(q),
        "_bq",
        bq,
        "_bk",
        bk,
        "_bd",
        bd,
        "_align_Q_",
        (align_Q ? 't' : 'n'),
        "_align_K_",
        (align_K ? 't' : 'n'),
        "_causal_",
        (do_causal ? 't' : 'n'));

    int64_t str_oD = 1;
    int64_t str_oH = o.shape(3);
    int64_t str_oL = o.shape(1) * str_oH;
    int64_t str_oB = o.shape(2) * str_oL;
    size_t data_size = o.shape(0) * str_oB;
    array::Flags flags{
        /* bool contiguous = */ 1,
        /* bool row_contiguous = */ 0,
        /* bool col_contiguous = */ 0,
    };
    o.set_data(
        allocator::malloc(o.nbytes()),
        data_size,
        {str_oB, str_oH, str_oL, str_oD},
        flags);

    auto lib = d.get_library("omlx_qwen35_prefill_kernels", current_binary_dir());
    auto& compute_encoder = metal::get_command_encoder(s);

    const int NQ = (qL + bq - 1) / bq;
    const int NQ_aligned = qL / bq;

    MTL::Size grid_dims = MTL::Size(NQ, H, B);
    MTL::Size group_dims = MTL::Size(32, wm, wn);

    // The kernel scans its whole key range inside one Metal dispatch, so the
    // per-dispatch wallclock grows linearly with kL. Past the macOS IOGPU
    // interactivity threshold the OS demotes (or kills) the command buffer
    // and long-context prefill collapses on pre-NAX GPUs (issue #2225,
    // mlx#3302). Boundss",
                    "phase": "batch",
                    "message": f"Batch {batch_size}x: pp1024/tg{request.generation_length}",
                    "current": current_test,
                    "total": total_tests,
                },
            )

            window_start = time.monotonic()
            batch_metrics = await _run_batch_test(
                engine=engine,
                prompts=batch_prompts[:batch_size],
                prompt_tokens=1024,
                max_tokens=request.generation_length,
                batch_size=batch_size,
            )
            batch_metrics["system_metrics"] = _sample_window(run, window_start)

            result = {
                "test_type": "batch",
                "pp": 1024,
                "tg": request.generation_length,
                **batch_metrics,
            }
            run.results.append(result)
            await _send_event(run, {"type": "result", "data": result})

        # Phase 5: Unload benchmark model
        await _send_event(
            run,
            {
                "type": "progress",
                "phase": "cleanup",
                "message": f"Unloading {request.model_id}...",
                "current": total_tests,
                "total": total_tests,
            },
        )
        try:
            await engine_pool._unload_engine(request.model_id)
            logger.info(f"Benchmark: unloaded {request.model_id} after benchmark")
        except Exception as e:
            logger.warning(f"Benchmark: failed to unload {request.model_id}: {e}")

        # Done
        overall_duration = time.perf_counter() - overall_start
        run.status = "completed"
        await _send_event(
            run,
            {
                "type": "done",
                "summary": {
                    "model_id": request.model_id,
                    "context_profile": request.context_profile.value,
                    "total_time": round(overall_duration, 1),
                    "total_tests": total_tests,
                },
            },
        )

        # Upload results to omlx.ai (failures don't affect benchmark status)
        try:
            await _upload_to_omlx_ai(run, engine_pool)
        except Exception as e:
            logger.warning(f"Benchmark upload to omlx.ai failed: {e}")
            await _send_event(
                run,
                {
                    "type": "upload_done",
                    "data": {
                        "owner_hash": None,
                        "total": 0,
                        "success": 0,
                        "failed": 0,
                        "error": str(e),
                    },
                },
            )

    except asyncio.CancelledError:
        run.status = "cancelled"
        await _send_event(
            run,
            {
                "type": "error",
                "message": "Benchmark cancelled by user",
            },
        )
        # Try to unload the model on cancellation
        try:
            await engine_pool._unload_engine(request.model_id)
        except Exception:
            pass

    except Exception as e:
        logger.error(f"Benchmark error: {e}", exc_info=True)
        run.status = "error"
        run.error_message = str(e)
        await _send_event(
            run,
            {
                "type": "error",
                "message": str(e),
            },
        )
        # Try to unload the model on error
        try:
            await engine_pool._unload_engine(request.model_id)
        except Exception:
            pass

    finally:
        if run.sampler is not None:
            try:
                run.sampler.stop()
            except Exception as e:  # noqa: BLE001
                logger.debug(f"Benchmark: sampler stop failed: {e}")
        _restore_speed_priority(engine_pool, previous_speed_priority)


async def _run_external_benchmark(run: BenchmarkRun) -> None:
    """Execute a benchmark run against an external OpenAI-compatible endpoint.

    No local model phases (unload/load/JIT warmup) and no community
      }
                .buttonStyle(.omlx(.normal, size: .small))
                .disabled(isLoading)
            }
        }

        ListGroup {
            if isLoading && models.isEmpty {
                FreeRow(isLast: true) {
                    HStack(spacing: 6) {
                        ProgressView().controlSize(.small)
                        Text(String(localized: "downloads.suggested.loading",
                                    defaultValue: "Loading recommendations…",
                                    comment: "Placeholder shown while the recommended-models list is fetching"))
                            .font(.omlxText(12))
                            .foregroundStyle(theme.textSecondary)
                    }
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding(.vertical, 14)
                }
            } else if models.isEmpty {
                FreeRow(isLast: true) {
                    Text(String(localized: "downloads.suggested.empty",
                                defaultValue: "No suggestions available right now.",
                                comment: "Empty-state message for the Suggested Models section"))
                        .font(.omlxText(12))
                        .foregroundStyle(theme.textTertiary)
                        .frame(maxWidth: .infinity, alignment: .center)
                        .padding(.vertical, 14)
                }
            } else {
                ForEach(Array(models.prefix(15).enumerated()), id: \.element.id) { idx, m in
                    let isLast = idx == min(models.count, 15) - 1
                    FreeRow(isLast: isLast) {
                        HStack(spacing: 10) {
                            Squircle(systemSymbol: "cpu",
                                     size: 26,
                                     gradient: SquircleGradient.models)
                            VStack(alignment: .leading, spacing: 2) {
                                Text(m.repoId)
                                    .font(.omlxText(13, weight: .medium))
                                    .foregroundStyle(theme.text)
                                    .lineLimit(1)
                                    .truncationMode(.tail)
                                Text(secondaryLine(for: m))
                                    .font(.omlxMono(11))
                                    .foregroundStyle(theme.textSecondary)
                                    .lineLimit(1)
                                    .truncationMode(.middle)
                            }
                            Spacer(minLength: 8)
                            Button {
                                onShowCard(m.repoId)
                            } label: {
                                Image(systemName: "info.circle")
                                    .font(.system(size: 11))
                            }
                            .buttonStyle(.omlx(.plain, size: .small))
                            .help(String(localized: "downloads.button.show_card",
                                         defaultValue: "View model card",
                                         comment: "Tooltip on the info button that opens a model's README sheet"))
                            Button {
                                onGet(m.repoId)
                            } label: {
                                Label(String(localized: "downloads.suggested.get",
                                             defaultValue: "Get",
                                             comment: "Compact button label that starts downloading a suggested model"),
                                      systemImage: "icloud.and.arrow.down")
                                    .labelStyle(.titleAndIcon)
                            }
                            .buttonStyle(.omlx(.normal, size: .small))
                        }
                    }
                }
            }
        }
    }

    private var hint: String? {
        models.isEmpty
            ? nil
            : String(lo  this.benchBenchId = data.bench_id;
                    this.connectBenchSSE(data.bench_id);
                } catch (err) {
                    console.error('Failed to start benchmark:', err);
                    this.benchError = window.t('js.error.start_benchmark_error').replace('{message}', err.message);
                    this.benchRunning = false;
                }
            },

            connectBenchSSE(benchId) {
                if (this.benchEventSource) {
                    this.benchEventSource.close();
                }

                const es = new EventSource(`/admin/api/bench/${benchId}/stream`);
                this.benchEventSource = es;

                es.onmessage = (event) => {
                    try {
                        const data = JSON.parse(event.data);

                        if (data.type === 'progress') {
                            this.benchProgress = {
                                phase: data.phase,
                                message: data.message,
                                current: data.current,
                                total: data.total,
                            };
                        } else if (data.type === 'result') {
                            // SSE replay-on-subscribe re-delivers every event on
                            // every reconnect (incl. page refresh), so append-only
                            // arrays must dedupe. Single rows are keyed by
                            // (pp, tg); batch rows by batch_size.
                            if (data.data.test_type === 'single') {
                                const exists = this.benchSingleResults.some(
                                    r => this.benchRequestedPp(r) === this.benchRequestedPp(data.data)
                                        && r.tg === data.data.tg
                                );
                                if (!exists) {
                                    this.benchSingleResults = [...this.benchSingleResults, data.data];
                                }
                            } else if (data.data.test_type === 'batch') {
                                const exists = this.benchBatchResults.some(
                                    r => r.batch_size === data.data.batch_size
                                );
                                if (!exists) {
                                    this.benchBatchResults = [...this.benchBatchResults, data.data];
                                }
                            }
                        } else if (data.type === 'done') {
                            // Benchmark tests done, uploading starts
                            this.benchUploading = true;
                            this.benchProgress = {
                                phase: 'upload',
                                message: 'Uploading to community benchmarks...',
                                current: 0,
                                total: 0,
                            };
                            this.loadModels();
                        } else if (data.type === 'upload') {
                            // Dedupe on replay: upload entries are unique by context_length.
                            const exists = this.benchUploadResults.some(
                                r => r.context_length === data.data.context_length
                            );
                            if (!exists) {
                                this.benchUploadResults = [...this.benchUploadResults, data.data];
                            }
                        } else if (data.type === 'upload_done') {
                            this.benchUploadDone = data.data;
                            this.benchUploadFlags = data.data.feature_flags || [];
                            this.benchUploading = false;
                            this.benchRunning = false;
                            this.benchProgress = null;
                            es.close();
                            this.benchEventSource = null;
                        } else if (data.ty the per-dispatch work by splitting the keys into
    // chunks of at most chunk_keys, each its own preemptible dispatch, and
    // fold the partials with logsumexp weights afterwards (mlx#3307).
    int64_t chunk_keys = kL;
    if (dispatch_budget_ > 0) {
      const int64_t work = int64_t(B) * H * qL * kL;
      if (work > dispatch_budget_) {
        // Very short chunks would re-dispatch the full query grid per sliver
        // of keys; 4 * bq keys is plenty to amortize the dead threadgroups.
        const int64_t min_chunk_keys = 4LL * bq;
        // The partial slab costs B*H*qL*D per chunk, so huge-qL calls (one
        // shot square prefill) cap the chunk count on memory instead of
        // honoring the dispatch budget exactly.
        const int64_t max_slab_bytes = 2LL << 30;
        const int64_t chunk_bytes = int64_t(B) * H * qL * bd * q.itemsize();
        const int64_t n_mem_cap =
            std::max<int64_t>(1, max_slab_bytes / std::max<int64_t>(chunk_bytes, 1));
        int64_t n_target = (work + dispatch_budget_ - 1) / dispatch_budget_;
        n_target = std::min(n_target, n_mem_cap);
        chunk_keys = (kL + n_target - 1) / n_target;
        chunk_keys = ((chunk_keys + bk - 1) / bk) * bk; // align to K tile
        chunk_keys = std::max(chunk_keys, min_chunk_keys);
      }
    }

    const int n_chunks = int((kL + chunk_keys - 1) / chunk_keys);

    if (n_chunks <= 1) {
      const int NK = (kL + bk - 1) / bk;
      const int NK_aligned = kL / bk;

      auto kernel = d.get_kernel(base_name, lib, hash_name, func_consts);
      compute_encoder.set_compute_pipeline_state(kernel);

      AttnParams params{
          /* int B = */ B,
          /* int H = */ H,
          /* int D = */ bd,
          /* int qL = */ qL,
          /* int kL = */ kL,
          /* int gqa_factor = */ gqa_factor,
          /* float scale = */ scale_,
          /* int NQ = */ NQ,
          /* int NK = */ NK,
          /* int NQ_aligned = */ NQ_aligned,
          /* int NK_aligned = */ NK_aligned,
          /* int qL_rem = */ (qL - NQ_aligned * bq),
          /* int kL_rem = */ (kL - NK_aligned * bk),
          /* int qL_off = */ (kL - qL),
          /* int64_t Q_strides[3] = */
          {q.strides(0), q.strides(1), q.strides(2)},
          /* int64_t K_strides[3] = */
          {k.strides(0), k.strides(1), k.strides(2)},
          /* int64_t V_strides[3] = */
          {v.strides(0), v.strides(1), v.strides(2)},
          /* int64_t O_strides[3] = */
          {o.strides(0), o.strides(1), o.strides(2)}};

      compute_encoder.set_input_array(q, 0);
      compute_encoder.set_input_array(k, 1);
      compute_encoder.set_input_array(v, 2);
      compute_encoder.set_output_array(o, 3);
      compute_encoder.set_bytes(params, 4);
      compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
      return;
    }

    // Chunked path: per-chunk normalized partials (input dtype) plus fp32
    // logsumexp rows, folded by the reduce kernel below.
    const int64_t o_chunk_stride = int64_t(B) * H * qL * bd;
    const int64_t lse_chunk_stride = int64_t(B) * H * qL;

    array o_part(
        {n_chunks, B, H, qL, bd}, o.dtype(), nullptr, std::vector<array>{});
    o_part.set_data(allocator::malloc(o_part.nbytes()));
    array lse_part(
        {n_chunks, B, H, qL}, float32, nullptr, std::vector<array>{});
    lse_part.set_data(allocator::malloc(lse_part.nbytes()));
    compute_encoder.add_temporary(o_part);
    compute_encoder.add_temporary(lse_part);

    const bool partials_true = true;
    for (int c = 0; c < n_chunks; ++c) {
      const int64_t k_start = int64_t(c) * chunk_keys;
      const int kL_c = int(std::min<int64_t>(chunk_keys, kL - k_start));
      const int NK_c = (kL_c + bk - 1) / bk;
      const int NK_aligned_c = kL_c / bk;
      const bool align_K_c = (kL_c % bk) == 0;

      metal::MTLFCList chunk_consts = {
          {&align_Q, MTL::DataType::DataTypeBool, 200},
          {&align_K_c, MTL::DataType::DataTypeBool, 201},
          {&has_mask, MTL::DataType::DataTypeBool, 300},
          {&do_causal, MTL::DataType:    upload — external numbers measure someone else's hardware.
    """
    request = run.request
    total_tests = len(request.prompt_lengths) + len(request.batch_sizes)
    current_test = 0
    overall_start = time.perf_counter()
    client = ExternalAPIClient(request.external)

    try:
        # Warmup doubles as preflight: fail fast on bad URL/key and on
        # endpoints that do not return streamed usage (hard requirement
        # for accurate token counts) before any long test runs.
        await _send_event(
            run,
            {
                "type": "progress",
                "phase": "warmup",
                "message": "Warming up external endpoint...",
                "current": 0,
                "total": total_tests,
            },
        )
        await client.stream_chat_completion(
            messages=[
                {
                    "role": "user",
                    "content": _generate_external_prompt(32, request.context_profile),
                }
            ],
            max_tokens=8,
            temperature=0.0,
        )
        logger.info("Benchmark: external endpoint warmup complete")

        # Single request tests
        for pp_len in request.prompt_lengths:
            current_test += 1
            await _send_event(
                run,
                {
                    "type": "progress",
                    "phase": "single",
                    "message": f"Single: pp{pp_len}/tg{request.generation_length}",
                    "current": current_test,
                    "total": total_tests,
                },
            )

            metrics = await _run_external_single_test(
                client=client,
                prompt=_generate_external_prompt(pp_len, request.context_profile),
                max_tokens=request.generation_length,
            )

            result = {
                "test_type": "single",
                "pp": metrics["prompt_tokens"],
                "requested_pp": pp_len,
                "tg": request.generation_length,
                **metrics,
            }
            run.results.append(result)
            await _send_event(run, {"type": "result", "data": result})

        # Batch tests: concurrent requests with unique pp1024 prompts
        for batch_size in request.batch_sizes:
            current_test += 1
            await _send_event(
                run,
                {
                    "type": "progress",
                    "phase": "batch",
                    "message": f"Batch {batch_size}x: pp1024/tg{request.generation_length}",
                    "current": current_test,
                    "total": total_tests,
                },
            )

            batch_metrics = await _run_external_batch_test(
                client=client,
                prompts=[
                    _generate_external_prompt(1024, request.context_profile)
                    for _ in range(batch_size)
                ],
                max_tokens=request.generation_length,
                batch_size=batch_size,
            )

            result = {
                "test_type": "batch",
                "pp": batch_metrics["prompt_tokens"],
                "requested_pp": 1024,
                "tg": request.generation_length,
                **batch_metrics,
            }
            run.results.append(result)
            await _send_event(run, {"type": "result", "data": result})

        # Done
        overall_duration = time.perf_counter() - overall_start
        run.status = "completed"
        await _send_event(
            run,
            {
                "type": "done",
                "summary": {
                    "model_id": request.model_id,
                    "context_profile": request.context_profile.value,
                    "total_time": round(overall_duration, 1),
                    "total_tests": total_tests,
                },
            },
        )

        # External results measure remote hardware — never upload them to
        # the omlx.ai community leaderboard. Mirrors the experimental-
  calized: "downloads.suggested.hint.filtered_by_ram",
                     defaultValue: "Filtered by free RAM",
                     comment: "Subtitle hint on the Suggested Models header explaining the filter")
    }

    private func secondaryLine(for m: HFModelInfo) -> String {
        var bits: [String] = []
        if let p = m.paramsFormatted { bits.append(p) }
        if let s = m.sizeFormatted { bits.append(s) }
        if let dl = m.downloads { bits.append("\(formatNumber(dl)) ↓") }
        return bits.isEmpty ? "—" : bits.joined(separator: " · ")
    }
}

// MARK: - Sort

enum SuggestedSort: String, Hashable, CaseIterable {
    case downloads, params, size

    var label: String {
        switch self {
        case .downloads: return String(localized: "downloads.suggested.sort.downloads",
                                       defaultValue: "Most downloaded",
                                       comment: "Sort option: rank suggested models by download count")
        case .params:    return String(localized: "downloads.suggested.sort.params",
                                       defaultValue: "Parameters: high to low",
                                       comment: "Sort option: rank suggested models by parameter count, descending")
        case .size:      return String(localized: "downloads.suggested.sort.size",
                                       defaultValue: "Size: high to low",
                                       comment: "Sort option: rank suggested models by on-disk size, descending")
        }
    }
}

// MARK: - Helpers

func formatNumber(_ n: Int) -> String {
    let v = Double(n)
    if v >= 1e9 { return String(format: "%.1fB", v / 1e9) }
    if v >= 1e6 { return String(format: "%.1fM", v / 1e6) }
    if v >= 1e3 { return String(format: "%.1fK", v / 1e3) }
    return String(n)
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/IntegrationsScreen.swift =====

// PR 9 — Integrations.
//
// Routes Claude Code requests to local models or to the cloud, exposes the
// other named integrations (Codex / OpenCode / OpenClaw / Hermes / Pi /
// Copilot) as model popups with per-tool launch commands, and renders the
// Claude Code setup command — both the simple `omlx launch claude` form and
// an "Advanced" env-var recipe that targets the real `claude` binary
// directly. The model popups read their options from /admin/api/models so
// the user can only pick something the server actually has on disk.
//
// The OpenAI Compatibility section + Connected Apps from the design canvas
// are skipped: there are no matching server fields. We keep every shipped
// row honestly wired.

import SwiftUI

struct IntegrationsScreen: View {
    @Environment(AppServices.self) private var services
    @State private var vm = IntegrationsScreenVM()

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            ClaudeCodeSection(vm: vm, client: services.client)
            ClaudeSetupCommandSection(vm: vm)
            OtherIntegrationsSection(vm: vm, client: services.client)
            MCPSection(vm: vm, client: services.client)

            if let error = vm.lastError {
                Text(error)
                    .font(.omlxText(11))
                    .foregroundStyle(.red)
                    .padding(.horizontal, 18)
                    .padding(.top, 8)
            }
        }
        .task { await vm.load(client: services.client) }
    }
}

// MARK: - Claude Code

private struct ClaudeCodeSection: View {
    @Bindable var vm: IntegrationsScreenVM
    let client: OMLXClient

    var body: some View {
        SectionHeader(
            String(localized: "integrations.section.claude_code",
                   defaultValue: "Claude Code",
                   comment: "Section header for the Claude Code integration"),
            subtitle: String(localized: "integrations.section.claude_code.sub",
                             defaultValue: "Route Claude Code requests to local models or the cloud",
                             comment: "Subtitle for the Claude Code section")
        )

pe === 'upload_skipped') {
                            this.benchUploadSkipped = {
                                reason: data.reason || 'external_endpoint',
                                features: data.features || [],
                            };
                            this.benchUploading = false;
                            this.benchRunning = false;
                            this.benchProgress = null;
                            es.close();
                            this.benchEventSource = null;
                            this.loadModels();
                        } else if (data.type === 'error') {
                            this.benchError = data.message;
                            this.benchRunning = false;
                            this.benchProgress = null;
                            es.close();
                            this.benchEventSource = null;
                            this.loadModels();
                        }

                    } catch (err) {
                        console.error('Failed to parse SSE event:', err);
                    }
                };

                es.onerror = () => {
                    if (this.benchRunning) {
                        this.benchError = window.t('js.error.benchmark_connection_lost');
                        this.benchRunning = false;
                        this.benchProgress = null;
                    }
                    es.close();
                    this.benchEventSource = null;
                };
            },

            async cancelBenchmark() {
                if (!this.benchBenchId) return;
                try {
                    await fetch(`/admin/api/bench/${this.benchBenchId}/cancel`, { method: 'POST' });
                } catch (err) {
                    console.error('Failed to cancel benchmark:', err);
                }
                // SSE handler will update state when error/done event arrives
            },

            // Context benchmark functions
            async startContextBenchmark() {
                if (!this.ctxBenchModelId || this.ctxBenchRunning) return;

                this.ctxBenchRunning = true;
                this.ctxBenchProgress = null;
                this.ctxBenchResult = null;
                this.ctxBenchError = '';
                this.ctxBenchBenchId = null;

                try {
                    const response = await fetch('/admin/api/bench/context/start', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            model_id: this.ctxBenchModelId,
                            target_tokens: this.ctxBenchTarget,
                        }),
                    });

                    if (response.status === 401) {
                        window.location.href = '/admin';
                        return;
                    }

                    if (!response.ok) {
                        const data = await response.json();
                        this.ctxBenchError = data.detail || window.t('js.error.start_context_bench_failed');
                        this.ctxBenchRunning = false;
                        return;
                    }

                    const data = await response.json();
                    this.ctxBenchBenchId = data.bench_id;
                    this.connectContextBenchSSE(data.bench_id);
                } catch (err) {
                    console.error('Failed to start context benchmark:', err);
                    this.ctxBenchError = window.t('js.error.start_context_bench_failed');
                    this.ctxBenchRunning = false;
                }
            },

            connectContextBenchSSE(benchId) {
                if (this.ctxBenchEventSource) {
                    this.ctxBenchEventSource.close();
                }

                const es = new EventSource(`/admin/api/bench/context/${benchId}/stream`);
                this.ctxBenchEventSource = es;

                es.onmessage = (event) => {
                  :DataTypeBool, 301},
          {&has_sinks, MTL::DataType::DataTypeBool, 302},
          {&has_block_mask, MTL::DataType::DataTypeBool, 303},
          {&has_block_token_mask, MTL::DataType::DataTypeBool, 304},
          {&has_block_indices, MTL::DataType::DataTypeBool, 305},
          {&partials_true, MTL::DataType::DataTypeBool, 306}};

      std::string chunk_hash;
      concatenate(
          chunk_hash,
          "omlx_qwen35_fa256_part_",
          type_to_name(q),
          "_bq",
          bq,
          "_bk",
          bk,
          "_bd",
          bd,
          "_align_Q_",
          (align_Q ? 't' : 'n'),
          "_align_K_",
          (align_K_c ? 't' : 'n'),
          "_causal_",
          (do_causal ? 't' : 'n'));

      auto kernel = d.get_kernel(base_name, lib, chunk_hash, chunk_consts);
      compute_encoder.set_compute_pipeline_state(kernel);

      AttnParams params{
          /* int B = */ B,
          /* int H = */ H,
          /* int D = */ bd,
          /* int qL = */ qL,
          /* int kL = */ kL_c,
          /* int gqa_factor = */ gqa_factor,
          /* float scale = */ scale_,
          /* int NQ = */ NQ,
          /* int NK = */ NK_c,
          /* int NQ_aligned = */ NQ_aligned,
          /* int NK_aligned = */ NK_aligned_c,
          /* int qL_rem = */ (qL - NQ_aligned * bq),
          /* int kL_rem = */ (kL_c - NK_aligned_c * bk),
          // Global position of local query row 0 relative to this chunk's
          // first key; negative once the chunk starts past early rows.
          /* int qL_off = */ int((int64_t(kL) - qL) - k_start),
          /* int64_t Q_strides[3] = */
          {q.strides(0), q.strides(1), q.strides(2)},
          /* int64_t K_strides[3] = */
          {k.strides(0), k.strides(1), k.strides(2)},
          /* int64_t V_strides[3] = */
          {v.strides(0), v.strides(1), v.strides(2)},
          // Partial slab is contiguous (B, H, qL, D) per chunk.
          /* int64_t O_strides[3] = */
          {int64_t(H) * qL * bd, int64_t(qL) * bd, int64_t(bd)}};

      compute_encoder.set_input_array(q, 0);
      compute_encoder.set_input_array(
          k, 1, k_start * k.strides(2) * k.itemsize());
      compute_encoder.set_input_array(
          v, 2, k_start * v.strides(2) * v.itemsize());
      compute_encoder.set_output_array(o, 3);
      compute_encoder.set_bytes(params, 4);
      compute_encoder.set_output_array(
          o_part, 14, c * o_chunk_stride * o_part.itemsize());
      compute_encoder.set_output_array(
          lse_part, 15, c * lse_chunk_stride * lse_part.itemsize());
      compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
    }

    std::string reduce_name;
    concatenate(
        reduce_name, "omlx_qwen35_fa256_chunk_reduce_", type_to_name(q));
    auto reduce_kernel = d.get_kernel(reduce_name, lib);
    compute_encoder.set_compute_pipeline_state(reduce_kernel);

    AttnChunkReduceParams reduce_params{
        /* int C = */ n_chunks,
        /* int H = */ H,
        /* int qL = */ qL,
        /* int D = */ bd,
        /* int64_t o_chunk_stride = */ o_chunk_stride,
        /* int64_t lse_chunk_stride = */ lse_chunk_stride,
        /* int64_t O_strides[3] = */ {o.strides(0), o.strides(1), o.strides(2)}};

    compute_encoder.set_input_array(o_part, 0);
    compute_encoder.set_input_array(lse_part, 1);
    compute_encoder.set_output_array(o, 2);
    compute_encoder.set_bytes(reduce_params, 3);

    MTL::Size reduce_grid = MTL::Size(bd / 4, qL, int64_t(B) * H);
    MTL::Size reduce_group = MTL::Size(bd / 4, std::max(1, 256 / (bd / 4)), 1);
    compute_encoder.dispatch_threads(reduce_grid, reduce_group);
  }

  DEFINE_NAME(OMLXQwen35Fa256Attention)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs = static_cast<const Qwen35Fa256AttentionPrimitive&>(other);
    return scale_ == rhs.scale_ && causal_ == rhs.causal_ &&
        q_block_ == rhs.q_block_ && k_block_ == rhs.k_block_ &&
        dispatch_budget_ == rhs.dispatch_budget_;
  }
  auto state() const {
    return std::make_t      # features skip so REST pollers see the same upload_state shape.
        run.upload_state["phase"] = "skipped"
        run.upload_state["skipped_reason"] = "external_endpoint"
        await _send_event(
            run,
            {
                "type": "upload_skipped",
                "reason": "external_endpoint",
                "features": [],
            },
        )

    except asyncio.CancelledError:
        run.status = "cancelled"
        await _send_event(
            run,
            {
                "type": "error",
                "message": "Benchmark cancelled by user",
            },
        )
    except Exception as e:
        logger.error(f"External benchmark error: {e}", exc_info=True)
        run.status = "error"
        run.error_message = str(e)
        await _send_event(
            run,
            {
                "type": "error",
                "message": str(e),
            },
        )
    finally:
        await client.aclose()


# ===== FILE: omlx/admin/build_css.py =====

#!/usr/bin/env python3
"""Build script for Tailwind CSS compilation.

Downloads Tailwind v3 standalone CLI if needed and compiles CSS.
Requires no Node.js installation.

Usage:
    cd omlx/omlx/admin
    python build_css.py          # Build minified CSS
    python build_css.py --watch  # Watch mode for development
"""

import platform
import subprocess
import sys
import urllib.request
from pathlib import Path

TAILWIND_VERSION = "v3.4.17"
ADMIN_DIR = Path(__file__).parent


def get_binary_name() -> str:
    """Get platform-specific Tailwind CLI binary name."""
    machine = platform.machine().lower()
    system = platform.system().lower()
    if system == "darwin":
        arch = "arm64" if machine == "arm64" else "x64"
        return f"tailwindcss-macos-{arch}"
    elif system == "linux":
        arch = "arm64" if "aarch64" in machine else "x64"
        return f"tailwindcss-linux-{arch}"
    raise RuntimeError(f"Unsupported platform: {system} {machine}")


def ensure_binary() -> Path:
    """Download Tailwind standalone CLI if not present."""
    binary_name = get_binary_name()
    binary_path = ADMIN_DIR / binary_name

    if binary_path.exists():
        return binary_path

    url = (
        f"https://github.com/tailwindlabs/tailwindcss/releases/download/"
        f"{TAILWIND_VERSION}/{binary_name}"
    )
    print(f"Downloading Tailwind CSS {TAILWIND_VERSION}...")
    print(f"  {url}")
    urllib.request.urlretrieve(url, binary_path)
    binary_path.chmod(0o755)
    print(f"  Saved to {binary_path}")
    return binary_path


def main() -> None:
    binary = ensure_binary()

    input_css = ADMIN_DIR / "src" / "input.css"
    output_css = ADMIN_DIR / "static" / "css" / "tailwind.css"
    config = ADMIN_DIR / "tailwind.config.js"

    output_css.parent.mkdir(parents=True, exist_ok=True)

    cmd = [
        str(binary),
        "-i", str(input_css),
        "-o", str(output_css),
        "-c", str(config),
        "--minify",
    ]

    if "--watch" in sys.argv:
        cmd.append("--watch")
        print("Watching for changes... (Ctrl+C to stop)")

    print(f"Building: {' '.join(cmd)}")
    result = subprocess.run(cmd)

    if result.returncode == 0 and "--watch" not in sys.argv:
        size = output_css.stat().st_size
        print(f"Output: {output_css} ({size:,} bytes)")
    sys.exit(result.returncode)


if __name__ == "__main__":
    main()


# ===== FILE: omlx/admin/context_benchmark.py =====

# SPDX-License-Identifier: Apache-2.0
"""Context window benchmark for oMLX admin panel.

Measures the largest prompt the current machine can actually prefill for
a model, then writes the result into the model's ``max_context_window``
setting so clients get an honest upfront limit instead of mid-prefill
aborts.

Method: a short calibration prefill seeds the scheduler's transient
tracker, then the deterministic admission boundary is found by bisecting
``scheduler.preflight_or_raise`` in-process — microseconds per probe, no
GPU work. One real prefill at the (2k-floored) boundary verifies it end
to end; on a mid-        ListGroup {
            Row(label: String(localized: "integrations.claude.mode",
                              defaultValue: "Mode",
                              comment: "Row label for the Claude Code mode segmented control")) {
                Segmented(
                    selection: vm.bind($vm.claudeMode, save: {
                        Task { await vm.save(.claudeMode, client: client) }
                    }),
                    options: [
                        ("cloud", String(localized: "integrations.claude.mode.cloud",
                                          defaultValue: "Cloud",
                                          comment: "Claude Code mode option: route to cloud")),
                        ("local", String(localized: "integrations.claude.mode.local",
                                          defaultValue: "Local",
                                          comment: "Claude Code mode option: route to local server")),
                    ]
                )
            }
            if vm.claudeMode == "local" {
                Row(label: String(localized: "integrations.claude.opus",
                                  defaultValue: "Opus tier",
                                  comment: "Row label for the Opus model picker")) {
                    Popup(
                        selection: vm.bind($vm.opusModel, save: {
                            Task { await vm.save(.opusModel, client: client) }
                        }),
                        width: 220,
                        options: vm.modelOptions
                    )
                }
                Row(label: String(localized: "integrations.claude.sonnet",
                                  defaultValue: "Sonnet tier",
                                  comment: "Row label for the Sonnet model picker")) {
                    Popup(
                        selection: vm.bind($vm.sonnetModel, save: {
                            Task { await vm.save(.sonnetModel, client: client) }
                        }),
                        width: 220,
                        options: vm.modelOptions
                    )
                }
                Row(
                    label: String(localized: "integrations.claude.haiku",
                                  defaultValue: "Haiku tier",
                                  comment: "Row label for the Haiku model picker"),
                    sublabel: String(localized: "integrations.claude.haiku.sub",
                                     defaultValue: "Used for background tasks and tool calls",
                                     comment: "Sublabel for the Haiku tier picker")
                ) {
                    Popup(
                        selection: vm.bind($vm.haikuModel, save: {
                            Task { await vm.save(.haikuModel, client: client) }
                        }),
                        width: 220,
                        options: vm.modelOptions
                    )
                }
            }
            Row(
                label: String(localized: "integrations.claude.context_scaling",
                              defaultValue: "Context scaling",
                              comment: "Row label for the Claude Code context scaling toggle"),
                sublabel: String(localized: "integrations.claude.context_scaling.sub",
                                 defaultValue: "Stretch context windows for long agentic sessions",
                                 comment: "Sublabel for the context scaling toggle"),
                isLast: !vm.contextScaling
            ) {
                Toggle("", isOn: vm.bind($vm.contextScaling, save: {
                    Task { await vm.save(.contextScaling, client: client) }
                }))
                .labelsHidden().toggleStyle(.switch)
            }
            if vm.contextScaling {
                Row(
                    label: String(localized: "integrations.claude.target_context",
                                  defaultValue: "Target context size",
                                  comment: "Row l  try {
                        const data = JSON.parse(event.data);

                        if (data.type === 'progress') {
                            this.ctxBenchProgress = {
                                phase: data.phase,
                                progress: data.progress,
                                message: data.message,
                            };
                        } else if (data.type === 'result') {
                            this.ctxBenchResult = data.data;
                        } else if (data.type === 'done') {
                            this.ctxBenchRunning = false;
                            this.ctxBenchProgress = null;
                            es.close();
                            this.ctxBenchEventSource = null;
                            // The applied setting changed the model row.
                            this.loadModels();
                        } else if (data.type === 'error') {
                            this.ctxBenchError = data.message;
                            this.ctxBenchRunning = false;
                            this.ctxBenchProgress = null;
                            es.close();
                            this.ctxBenchEventSource = null;
                            this.loadModels();
                        }
                    } catch (err) {
                        console.error('Failed to parse SSE event:', err);
                    }
                };

                es.onerror = () => {
                    if (this.ctxBenchRunning) {
                        this.ctxBenchError = window.t('js.error.benchmark_connection_lost');
                        this.ctxBenchRunning = false;
                        this.ctxBenchProgress = null;
                    }
                    es.close();
                    this.ctxBenchEventSource = null;
                };
            },

            async cancelContextBenchmark() {
                if (!this.ctxBenchBenchId) return;
                try {
                    await fetch(`/admin/api/bench/context/${this.ctxBenchBenchId}/cancel`, { method: 'POST' });
                } catch (err) {
                    console.error('Failed to cancel context benchmark:', err);
                }
                // SSE handler will update state when the error event arrives
            },

            async loadCtxBenchState() {
                // Attach to an in-flight context bench (page refresh, other tab).
                try {
                    const resp = await fetch('/admin/api/bench/context/active');
                    if (!resp.ok) return;
                    const data = await resp.json();
                    if (!data.running || !data.bench_id) return;
                    if (this.ctxBenchBenchId === data.bench_id && this.ctxBenchEventSource) {
                        return;
                    }
                    this.ctxBenchBenchId = data.bench_id;
                    this.ctxBenchModelId = data.model_id;
                    if (data.target_tokens) this.ctxBenchTarget = data.target_tokens;
                    this.ctxBenchRunning = true;
                    this.ctxBenchResult = null;
                    this.ctxBenchError = '';
                    this.connectContextBenchSSE(data.bench_id);
                } catch (err) {
                    console.error('Failed to load context bench state:', err);
                }
            },

            ctxBenchCappedByLabel() {
                const capped = this.ctxBenchResult?.capped_by;
                if (capped === 'target') return window.t('ctx_bench.capped.target');
                if (capped === 'native') return window.t('ctx_bench.capped.native');
                return window.t('ctx_bench.capped.memory');
            },

            // Native context length of the selected bench model (0 = unknown).
            ctxBenchNativeLimit() {
                const m = this.models.find(m => m.id === this.ctxBenchModelId);
                return (m && m.model_context_length) || 0;
            },

            // Target presets the selected model can uple(
        nullptr, scale_, causal_, q_block_, k_block_, dispatch_budget_);
  }

 private:
  float scale_;
  bool causal_;
  int q_block_;
  int k_block_;
  int64_t dispatch_budget_;
};

class Qwen35QAffineQmmTPrimitive : public Primitive {
 public:
  Qwen35QAffineQmmTPrimitive(
      Stream stream,
      int bits,
      int variant,
      bool use_nax,
      int nax_variant,
      int group_size)
      : Primitive(stream),
        bits_(bits),
        variant_(variant),
        use_nax_(use_nax),
        nax_variant_(nax_variant),
        group_size_(group_size) {
    if (!qwen_q_affine_bits_supported(bits_)) {
      std::ostringstream msg;
      msg << "Unsupported Qwen affine qmm bits " << bits_ << ".";
      throw std::invalid_argument(msg.str());
    }
    if (group_size_ != 64 && group_size_ != 128) {
      std::ostringstream msg;
      msg << "Unsupported Qwen affine qmm group_size " << group_size_ << ".";
      throw std::invalid_argument(msg.str());
    }
    (void)qwen_q_affine_variant(variant_);
    if (use_nax_) {
      (void)qwen_q_affine_nax_variant(nax_variant_);
    }
  }

  static bool unsupported(
      const array& x,
      const array& weight,
      const array& scales,
      const array& biases,
      int bits,
      int variant,
      int group_size,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (!qwen_q_affine_bits_supported(bits)) {
      return true;
    }
    if (group_size != 64 && group_size != 128) {
      return true;
    }
    if (x.dtype() != float16 && x.dtype() != bfloat16) {
      return true;
    }
    if (weight.dtype() != uint32 || scales.dtype() != x.dtype() ||
        biases.dtype() != x.dtype()) {
      return true;
    }
    if (x.ndim() < 2 || weight.ndim() != 2 || scales.ndim() != 2 ||
        biases.ndim() != 2) {
      return true;
    }
    if (!row_contiguous(x) || !row_contiguous(weight) ||
        !row_contiguous(scales) || !row_contiguous(biases)) {
      return true;
    }

    const auto cfg = qwen_q_affine_variant(variant);
    const int K = x.shape(-1);
    const int N = weight.shape(0);
    if (K <= 0 || N <= 0 || x.size() <= 0 || K % group_size != 0 ||
        K % cfg.bk != 0 || N % cfg.bn != 0) {
      return true;
    }
    if (!qwen_q_affine_packed_shape_matches(weight.shape(1), K, bits) ||
        scales.shape(0) != N || scales.shape(1) != K / group_size ||
        biases.shape() != scales.shape()) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("Qwen35QAffineQmmTPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x = inputs[0];
    const auto& weight = inputs[1];
    const auto& scales = inputs[2];
    const auto& biases = inputs[3];

    out.set_data(allocator::malloc(out.nbytes()));

    const int K = x.shape(-1);
    const int N = weight.shape(0);
    const int M = x.size() / K;

    auto& compute_encoder = metal::get_command_encoder(s);
    auto encode = [&](MTL::ComputePipelineState* kernel,
                      int bm,
                      int bn,
                      int wm,
                      int wn) {
      compute_encoder.set_compute_pipeline_state(kernel);
      compute_encoder.set_input_array(weight, 0);
      compute_encoder.set_input_array(scales, 1);
      compute_encoder.set_input_array(biases, 2);
      compute_encoder.set_input_array(x, 3);
      compute_encoder.set_output_array(out, 4);
      compute_encoder.set_bytes(K, 5);
      compute_encoder.set_bytes(N, 6);
      compute_encoder.set_bytes(M, 7);

      MTL::Size grid_dims((N + bn - 1) / bn, (M + bm - 1) / bm, 1);
      MTL::Size group_dims(32, wm, wn);
      compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
    };

    if (use_nax_ && nax_qmm_runtime_ok.load(std::memory_order_relaxed)) {
     prefill abort a single conservative retry runs, sized
from where the first prefill actually died (90% of its processed
tokens). A clean first-try completion instead climbs upward in 1.2x
extension probes until the cap or the first failure, since a boundary
that binds near the ceiling can be conservative. Probe requests carry
``skip_cache_store`` and the bench clears the model's paged cache
between probes, so nothing leaks into the prefix/SSD cache tiers.
"""

import asyncio
import contextlib
import gc
import logging
import time
import uuid
from collections.abc import Callable
from dataclasses import dataclass, field
from typing import Any

from pydantic import BaseModel, field_validator

from ..exceptions import PrefillMemoryAbortedError, PrefillMemoryExceededError
from ..prefill_progress import get_prefill_tracker
from .benchmark import _generate_prompt

logger = logging.getLogger(__name__)

# Module-level storage for context benchmark runs
_context_runs: dict[str, "ContextBenchmarkRun"] = {}

# Valid measurement targets (16k .. 512k)
VALID_TARGET_TOKENS = [16384, 32768, 65536, 131072, 262144, 524288]

# Applied values are floored to this granularity (user-facing "2k units").
_APPLY_GRANULARITY = 2048

# Smallest boundary worth reporting; below this the machine cannot hold a
# usable context for the model at all.
_MIN_USEFUL_TOKENS = 2048

# Calibration prefill size — seeds the transient tracker EWMA and the
# GDN/Mamba fixed-state measurement before the analytic search.
_CALIBRATION_TOKENS = 4096

# Two real-prefill attempts total: the boundary try, then one
# conservative retry informed by where the first prefill actually
# aborted. More rounds add minutes of near-ceiling crawling for
# marginal precision. Instant admission rejections (nothing prefilled)
# do not consume an attempt; the spin cap bounds those instead.
_MAX_VERIFY_ATTEMPTS = 2
_MAX_VERIFY_SPINS = 6

# Retry candidate = this fraction of the token count the aborted prefill
# actually completed — physical evidence of what fits, with headroom.
_ABORT_EVIDENCE_SAFETY = 0.9

# When the verify completed straight at the analytic boundary (no abort
# evidence, memory-bound), extension probes climb in steps of this
# factor until the cap or the first failure — a conservative boundary
# gets the chance to prove more. Only COMPLETED extensions are ever
# applied; a failed one keeps the last completed value.
_EXTENSION_FACTOR = 1.2

_CTX_TERMINAL_TYPES = frozenset({"done", "error"})

# Overall progress bands per phase (0-100).
_PROGRESS_BANDS = {
    "prepare": (0.0, 8.0),
    "calibrate": (8.0, 16.0),
    "estimate": (16.0, 20.0),
    "verify": (20.0, 95.0),
    "apply": (95.0, 100.0),
}


class ContextBenchmarkRequest(BaseModel):
    """Request model for starting a context benchmark."""

    model_id: str
    target_tokens: int = 131072

    @field_validator("target_tokens")
    @classmethod
    def validate_target_tokens(cls, v: int) -> int:
        if v not in VALID_TARGET_TOKENS:
            raise ValueError(
                f"Invalid target {v}. Must be one of {VALID_TARGET_TOKENS}"
            )
        return v


@dataclass
class ContextBenchmarkRun:
    """Tracks the state of a running context benchmark.

    Same SSE delivery model as ``BenchmarkRun``: events are appended to
    `events` under `cond`, subscribers replay from offset 0 then wait for
    new entries, and `terminal` closes the stream. `phase` / `progress` /
    `message` mirror the latest progress event so REST pollers (the
    native app) never need to parse the event log.
    """

    bench_id: str
    request: ContextBenchmarkRequest
    status: str = "running"  # running, completed, cancelled, error
    events: list[dict] = field(default_factory=list)
    cond: asyncio.Condition = field(default_factory=asyncio.Condition)
    terminal: bool = False
    task: asyncio.Task | None = None
    phase: str = "prepare"
    progress: float = 0.0
    message: str = ""
    result: dict | None = None
    error_message: str = ""


def get_run(bench_id: str) -> "ContextBenchmarkRun | None":
    """Get a abel for the Claude Code target context size field"),
                    sublabel: String(localized: "integrations.claude.target_context.sub",
                                     defaultValue: "Per-request context window Claude Code will scale toward",
                                     comment: "Sublabel for the target context size field"),
                    isLast: true
                ) {
                    TextInput(
                        text: $vm.targetContextSizeText,
                        mono: true,
                        suffix: "tk",
                        width: 130
                    )
                }
            }
        }
        if vm.contextScaling {
            HStack {
                Spacer()
                Button(String(localized: "integrations.target_context.apply",
                              defaultValue: "Apply",
                              comment: "Apply button for the Claude Code target context size field")) {
                    Task { await vm.save(.targetContextSize, client: client) }
                }
                .buttonStyle(.omlx(.primary))
                .disabled(!vm.hasPendingContextSizeChange)
            }
            .padding(.horizontal, 18)
            .padding(.top, 6)
        }
    }
}

// MARK: - Setup command (Claude Code)

/// Houses both the primary `omlx launch claude` block and the "Advanced"
/// env-var recipe that points the real `claude` binary at the local server.
/// Mirrors `claudeCodeCommand` in `omlx/admin/static/js/dashboard.js`.
private struct ClaudeSetupCommandSection: View {
    var vm: IntegrationsScreenVM
    @State private var showAdvanced = false
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        SectionHeader(String(localized: "integrations.section.setup_command",
                              defaultValue: "Setup Command",
                              comment: "Section header for the Claude Code setup command block"))

        VStack(alignment: .leading, spacing: 10) {
            CommandBlock(command: vm.claudeLaunchCommand)

            DisclosureGroup(isExpanded: $showAdvanced) {
                VStack(alignment: .leading, spacing: 6) {
                    Text(vm.claudeMode == "cloud"
                         ? String(localized: "integrations.setup.advanced.cloud",
                                  defaultValue: "Resets Anthropic env vars so the real `claude` binary talks to the cloud.",
                                  comment: "Explanation of the advanced env recipe in cloud mode")
                         : String(localized: "integrations.setup.advanced.local",
                                  defaultValue: "Points the real `claude` binary at your local oMLX server.",
                                  comment: "Explanation of the advanced env recipe in local mode"))
                        .font(.omlxText(11.5))
                        .foregroundStyle(theme.textSecondary)
                    CommandBlock(command: vm.claudeEnvRecipe)
                }
                .padding(.top, 6)
            } label: {
                Text(String(localized: "integrations.setup.advanced.label",
                            defaultValue: "Advanced — run `claude` directly",
                            comment: "Disclosure label revealing the advanced env-var recipe for running claude directly"))
                    .font(.omlxText(12, weight: .medium))
                    .foregroundStyle(theme.textSecondary)
            }
            .padding(.horizontal, 4)
        }
        .padding(.horizontal, 14)
    }
}

/// Shared monospaced command block with a copy button. Used by both the
/// Claude Code section and each per-tool row in OtherIntegrationsSection.
private struct CommandBlock: View {
    let command: String
    var caption: String? = nil
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        ZStack(alignment: .topTrailing) {
            VStack(alignment: .leading, spacing: 4) {
                Text(caption ?? String(localized: "integrations.command.terminal_caption",actually reach. Unknown
            // native -> full list; native below the smallest preset -> keep
            // the smallest (the server caps the search at native anyway).
            ctxBenchTargetOptions() {
                const all = [16384, 32768, 65536, 131072, 262144, 524288];
                const native = this.ctxBenchNativeLimit();
                if (!native) return all;
                const filtered = all.filter(t => t <= native);
                return filtered.length ? filtered : [all[0]];
            },

            // Keep the selected target inside the model's reachable presets.
            ctxBenchClampTarget() {
                const options = this.ctxBenchTargetOptions();
                if (!options.includes(this.ctxBenchTarget)) {
                    this.ctxBenchTarget = options[options.length - 1];
                }
            },

            // Narrow-patch save of the global Prefill Priority setting from
            // the bench tab (mirrors the Settings row; applied live server-side).
            async saveCtxBenchPriority(value) {
                if (this.ctxBenchRunning) return;
                const prev = this.globalSettings.scheduler.prefill_priority;
                if (prev === value) return;
                this.globalSettings.scheduler.prefill_priority = value;
                try {
                    const resp = await fetch('/admin/api/global-settings', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ prefill_priority: value }),
                    });
                    if (!resp.ok) throw new Error('HTTP ' + resp.status);
                } catch (err) {
                    console.error('Failed to save prefill priority:', err);
                    this.globalSettings.scheduler.prefill_priority = prev;
                    this.ctxBenchError = window.t('js.error.save_prefill_priority_failed');
                }
            },

            benchGetSpeedup(batchResult) {
                const baseline = this.benchFindSingle(1024);
                if (!baseline || !baseline.gen_tps || baseline.gen_tps <= 0) return null;
                if (batchResult.tg_tps === null || batchResult.tg_tps === undefined) return null;
                return batchResult.tg_tps / baseline.gen_tps;
            },

            benchRequestedPp(result) {
                return result?.requested_pp ?? result?.pp;
            },

            benchFindSingle(requestedPp) {
                return this.benchSingleResults.find(
                    r => this.benchRequestedPp(r) === requestedPp
                );
            },

            benchSingleTestLabel(result) {
                const requested = this.benchRequestedPp(result);
                const actual = result?.pp;
                if (requested !== actual) {
                    return `pp${actual} (requested pp${requested})/tg${result.tg}`;
                }
                return `pp${actual}/tg${result.tg}`;
            },

            benchBatchPromptSummary() {
                const result = this.benchBatchResults[0];
                if (!result || result.requested_pp === undefined) {
                    return window.t('bench.results.batch.subtitle');
                }
                const requested = result.requested_pp;
                const minimum = result.prompt_tokens_min ?? result.pp;
                const maximum = result.prompt_tokens_max ?? result.pp;
                const actual = minimum === maximum
                    ? `actual pp${minimum}`
                    : `actual pp${minimum}-${maximum}`;
                return `requested pp${requested} / ${actual} / tg${result.tg}`;
            },

            // Unmeasured metrics (tpot_ms/gen_tps/tg_tps, plus ttft/pp when
            // no content delta was ever observed) come through as null
            // rather than a misleading 0.0 — render them as N/A.
            benchFmtNum(value, decimals, suffix = '') {
                if (value === null || value === undefined) retu const auto cfg = qwen_q_affine_nax_variant(nax_variant_);
      std::string kname;
      concatenate(
          kname,
          "qwen35_q",
          bits_,
          "_affine_qmm_t_nax_",
          qwen_type_name(x.dtype()),
          "_bm_",
          cfg.bm,
          "_bk_",
          cfg.bk,
          "_bn_",
          cfg.bn,
          "_wm_",
          cfg.wm,
          "_wn_",
          cfg.wn);
      try {
        auto lib = d.get_library(kNaxMetallibName, current_binary_dir());
        auto kernel = d.get_kernel(kname, lib);
        encode(kernel, cfg.bm, cfg.bn, cfg.wm, cfg.wn);
        return;
      } catch (const std::exception&) {
        // The metallib next to the extension predates the NAX kernels (or
        // pipeline creation was rejected); disable NAX for the process and
        // fall through to the classic kernel, which unsupported() already
        // validated for these shapes.
        nax_qmm_runtime_ok.store(false, std::memory_order_relaxed);
      }
    }

    const auto cfg = qwen_q_affine_variant(variant_);
    std::string kname;
    concatenate(
        kname,
        "qwen35_q",
        bits_,
        group_size_ == 128 ? "_affine_qmm128_t_" : "_affine_qmm_t_",
        qwen_type_name(x.dtype()),
        "_bm_",
        cfg.bm,
        "_bk_",
        cfg.bk,
        "_bn_",
        cfg.bn);

    auto lib = d.get_library("omlx_qwen35_prefill_kernels", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    encode(kernel, cfg.bm, cfg.bn, 2, 2);
  }

  DEFINE_NAME(Qwen35QAffineQmmTPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& other) const override {
    const auto& rhs =
        static_cast<const Qwen35QAffineQmmTPrimitive&>(other);
    return bits_ == rhs.bits_ && variant_ == rhs.variant_ &&
        use_nax_ == rhs.use_nax_ && nax_variant_ == rhs.nax_variant_ &&
        group_size_ == rhs.group_size_;
  }
  auto state() const {
    return std::make_tuple(bits_, variant_, use_nax_, nax_variant_, group_size_);
  }

 private:
  int bits_;
  int variant_;
  bool use_nax_;
  int nax_variant_;
  int group_size_;
};

class Qwen35MoeWeightedSumPrimitive : public Primitive {
 public:
  explicit Qwen35MoeWeightedSumPrimitive(Stream stream) : Primitive(stream) {}

  static bool unsupported(
      const array& x_sorted,
      const array& inv_order,
      const array& scores,
      Stream s) {
    if (s.device == Device::cpu) {
      return true;
    }
    if (x_sorted.dtype() != float16 && x_sorted.dtype() != bfloat16) {
      return true;
    }
    if (scores.dtype() != float32 || inv_order.dtype() != uint32) {
      return true;
    }
    if (x_sorted.ndim() != 3 || x_sorted.shape(-2) != 1 ||
        scores.ndim() < 2 || inv_order.ndim() != 1) {
      return true;
    }
    if (!row_contiguous(x_sorted) || !row_contiguous(inv_order) ||
        !row_contiguous(scores)) {
      return true;
    }
    const int topk = scores.shape(-1);
    if ((topk != 6 && topk != 8) || x_sorted.shape(0) != scores.size() ||
        inv_order.size() != scores.size()) {
      return true;
    }
    return false;
  }

  void eval_cpu(
      const std::vector<array>& /* inputs */,
      std::vector<array>& /* outputs */) override {
    throw std::runtime_error("Qwen35MoeWeightedSumPrimitive has no CPU path.");
  }

  void eval_gpu(
      const std::vector<array>& inputs,
      std::vector<array>& outputs) override {
    auto& s = stream();
    auto& d = metal::device(s.device);
    auto& out = outputs[0];

    const auto& x_sorted = inputs[0];
    const auto& inv_order = inputs[1];
    const auto& scores = inputs[2];

    out.set_data(allocator::malloc(out.nbytes()));

    const int topk = scores.shape(-1);
    const int tokens = scores.size() / topk;
    const int D = x_sorted.shape(-1);

    constexpr bool use_tiled = true;
    constexpr int tiled_threads = 256;
    const int vec = (D % 4 == 0) ? 4 : 1;

    std::string kname;
    if (use_tiled) {
      concatenate(
          kname,
          "moe_weighted_sum_tiled_",
          qwen_type_name(x_sorted.dtype()),
       context benchmark run by ID."""
    return _context_runs.get(bench_id)


def get_active_run() -> "ContextBenchmarkRun | None":
    """Return the currently-running context benchmark, if any."""
    for run in _context_runs.values():
        if run.status == "running":
            return run
    return None


def create_run(request: ContextBenchmarkRequest) -> ContextBenchmarkRun:
    """Create and register a new context benchmark run."""
    bench_id = f"ctx-{uuid.uuid4().hex[:12]}"
    run = ContextBenchmarkRun(bench_id=bench_id, request=request)
    _context_runs[bench_id] = run
    return run


def cleanup_old_runs(max_runs: int = 10) -> None:
    """Remove old completed runs to prevent memory leaks."""
    completed = [
        (bid, r)
        for bid, r in _context_runs.items()
        if r.status in ("completed", "cancelled", "error")
    ]
    if len(completed) > max_runs:
        for bid, _ in completed[:-max_runs]:
            del _context_runs[bid]


async def _send_event(run: ContextBenchmarkRun, event: dict) -> None:
    """Append an event, mirror progress state, wake subscribers."""
    async with run.cond:
        run.events.append(event)
        if event.get("type") == "progress":
            run.phase = event.get("phase", run.phase)
            run.progress = float(event.get("progress", run.progress))
            run.message = event.get("message", run.message)
        if event.get("type") in _CTX_TERMINAL_TYPES:
            run.terminal = True
        run.cond.notify_all()


async def _progress(
    run: ContextBenchmarkRun, phase: str, fraction: float, message: str
) -> None:
    """Emit a progress event mapped into the phase's overall band."""
    lo, hi = _PROGRESS_BANDS.get(phase, (0.0, 100.0))
    overall = lo + (hi - lo) * min(1.0, max(0.0, fraction))
    await _send_event(
        run,
        {
            "type": "progress",
            "phase": phase,
            "progress": round(overall, 1),
            "message": message,
        },
    )


def floor_to_apply_granularity(tokens: int) -> int:
    """Floor a token count to the applied 2k granularity."""
    return (max(0, tokens) // _APPLY_GRANULARITY) * _APPLY_GRANULARITY


def ceil_to_apply_granularity(tokens: int) -> int:
    """Ceil a token count to the applied 2k granularity."""
    return -(-max(0, tokens) // _APPLY_GRANULARITY) * _APPLY_GRANULARITY


def bisect_admission(fits: Callable[[int], bool], lo: int, hi: int) -> int:
    """Largest n in [lo, hi] with fits(n) True; 0 if even lo fails.

    Assumes fits is monotone non-increasing over n (the admission
    formula is: estimate grows with n, limit is fixed).
    """
    if hi < lo:
        return 0
    if not fits(lo):
        return 0
    if fits(hi):
        return hi
    while hi - lo > 1:
        mid = (lo + hi) // 2
        if fits(mid):
            lo = mid
        else:
            hi = mid
    return lo


def _resolve_scheduler(engine: Any) -> Any | None:
    """Pool engine → async engine → core → scheduler (None when absent)."""
    async_core = getattr(engine, "_engine", None)
    core = getattr(async_core, "engine", None) if async_core is not None else None
    return getattr(core, "scheduler", None) if core is not None else None


def _resolve_core(engine: Any) -> Any | None:
    async_core = getattr(engine, "_engine", None)
    return getattr(async_core, "engine", None) if async_core is not None else None


def _guard_ready(scheduler: Any) -> bool:
    """preflight_or_raise no-ops unless all three of these hold."""
    return bool(
        getattr(scheduler, "_prefill_memory_guard", False)
        and getattr(scheduler, "_memory_hard_limit_bytes", 0) > 0
        and getattr(scheduler, "memory_monitor", None) is not None
    )


def _make_fits(scheduler: Any) -> Callable[[int], bool]:
    def fits(n: int) -> bool:
        try:
            scheduler.preflight_or_raise(num_prompt_tokens=n)
        except PrefillMemoryExceededError:
            return False
        return True

    return fits


def _clear_probe_residue(scheduler: Any) -> None:
    """Release probe KV blocks
                                       defaultValue: "$ Terminal",
                                       comment: "Caption above each shell command block"))
                    .font(.omlxText(10, weight: .semibold))
                    .foregroundStyle(theme.textTertiary)
                    .textCase(.uppercase)
                    .kerning(0.6)
                Text(command)
                    .font(.omlxMono(12))
                    .foregroundStyle(theme.text)
                    .textSelection(.enabled)
                    .frame(maxWidth: .infinity, alignment: .leading)
            }
            .padding(12)
            .background(theme.codeBg)
            .clipShape(RoundedRectangle(cornerRadius: theme.cornerRadius, style: .continuous))
            .overlay(
                RoundedRectangle(cornerRadius: theme.cornerRadius, style: .continuous)
                    .strokeBorder(theme.groupBorder, lineWidth: 0.5)
            )

            CopyButton(value: command)
                .padding(.top, 6)
                .padding(.trailing, 8)
        }
    }
}

private struct CopyButton: View {
    let value: String
    @State private var copied = false
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        Button {
            let pb = NSPasteboard.general
            pb.clearContents()
            pb.setString(value, forType: .string)
            copied = true
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.4) {
                copied = false
            }
        } label: {
            Image(systemName: copied ? "checkmark" : "document.on.document")
                .font(.system(size: 11, weight: .medium))
                .foregroundStyle(copied ? theme.successText : theme.textSecondary)
                .padding(5)
                .background(theme.controlBg)
                .clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous))
        }
        .buttonStyle(.plain)
    }
}

// MARK: - Other integrations

private struct OtherIntegrationsSection: View {
    @Bindable var vm: IntegrationsScreenVM
    let client: OMLXClient

    var body: some View {
        SectionHeader(
            String(localized: "integrations.section.other",
                   defaultValue: "Other Integrations",
                   comment: "Section header for the additional integrations list"),
            subtitle: String(localized: "integrations.section.other.sub",
                             defaultValue: "Default model + launcher command for each named integration",
                             comment: "Subtitle for the Other Integrations section")
        )

        ListGroup {
            IntegrationRow(
                name: String(localized: "integrations.tool.codex",
                             defaultValue: "Codex",
                             comment: "Display name for the Codex integration"),
                modelBinding: vm.bind($vm.codexModel, save: {
                    Task { await vm.save(.codexModel, client: client) }
                }),
                modelOptions: vm.modelOptions,
                command: vm.codexCommand,
                commandLabel: String(localized: "integrations.codex.cli",
                                     defaultValue: "CLI",
                                     comment: "Label for the Codex CLI launcher command"),
                secondaryCommand: vm.codexAppCommand,
                secondaryCommandLabel: String(localized: "integrations.codex.app",
                                             defaultValue: "Desktop App",
                                             comment: "Label for the Codex desktop app launcher command")
            )
            IntegrationRow(
                name: String(localized: "integrations.tool.opencode",
                             defaultValue: "OpenCode",
                             comment: "Display name for the OpenCode integration"),
                modelBinding: vm.bind($vm.opencodeModel, save: {
                    Task { await vm.save(.opencodeModel, client: client) }
                }),
          rn 'N/A';
                return value.toFixed(decimals) + suffix;
            },

            // Per-request pp TPS, null when the aggregate itself is unmeasured.
            benchPpPerReq(batchResult) {
                const pp = batchResult.pp_tps;
                if (pp === null || pp === undefined) return null;
                return pp / batchResult.batch_size;
            },

            benchFormatMemory(bytes) {
                if (!bytes || bytes === 0) return '-';
                const gb = bytes / (1024 * 1024 * 1024);
                if (gb >= 1) return gb.toFixed(2) + ' GB';
                const mb = bytes / (1024 * 1024);
                return mb.toFixed(0) + ' MB';
            },

            benchBuildText() {
                const pad = (s, w) => s.toString().padStart(w);
                const rpad = (s, w) => s.toString().padEnd(w);
                let lines = [];

                lines.push('oMLX - LLM inference, optimized for your Mac');
                lines.push('https://github.com/jundot/omlx');
                if (this.benchRunExternal) {
                    lines.push(`Benchmark Model: ${this.benchRunExternal.model} @ ${this.benchRunExternal.base_url}`);
                    lines.push('Engine: External OpenAI-compatible endpoint');
                } else {
                    lines.push(`Benchmark Model: ${this.benchModelId}`);
                    lines.push(`Engine: ${this.benchForceLmEngine ? 'Force mlx-lm' : 'Auto'}`);
                }
                lines.push(`Context: ${this.benchContextLabel(this.benchContextProfile)}`);
                lines.push('='.repeat(80));

                // Single Request Results
                if (this.benchSingleResults.length > 0) {
                    lines.push('');
                    lines.push('Single Request Results');
                    lines.push('-'.repeat(80));
                    const hdr = [rpad('Test', 32), pad('TTFT(ms)', 10), pad('TPOT(ms)', 10), pad('pp TPS', 12), pad('tg TPS', 12), pad('E2E(s)', 10), pad('Throughput', 12), pad('Peak Mem', 10)];
                    lines.push(hdr.join('  '));
                    for (const r of this.benchSingleResults) {
                        const row = [
                            rpad(this.benchSingleTestLabel(r), 32),
                            pad(this.benchFmtNum(r.ttft_ms, 1), 10),
                            pad(this.benchFmtNum(r.tpot_ms, 2), 10),
                            pad(this.benchFmtNum(r.processing_tps, 1, ' tok/s'), 12),
                            pad(this.benchFmtNum(r.gen_tps, 1, ' tok/s'), 12),
                            pad(r.e2e_latency_s.toFixed(3), 10),
                            pad(r.total_throughput.toFixed(1) + ' tok/s', 12),
                            pad(this.benchFormatMemory(r.peak_memory_bytes), 10),
                        ];
                        lines.push(row.join('  '));
                    }
                }

                // Helper for batch table text
                const buildBatchText = (title, subtitle, results) => {
                    if (results.length === 0) return;
                    const baseline = this.benchFindSingle(1024);
                    lines.push('');
                    lines.push(`${title}`);
                    lines.push(subtitle);
                    lines.push('-'.repeat(80));
                    const hdr = [rpad('Batch', 8), pad('tg TPS', 12), pad('Speedup', 8), pad('pp TPS', 12), pad('pp TPS/req', 12), pad('TTFT(ms)', 10), pad('E2E(s)', 10)];
                    lines.push(hdr.join('  '));
                    if (baseline) {
                        const row = [
                            rpad('1x', 8),
                            pad(this.benchFmtNum(baseline.gen_tps, 1, ' tok/s'), 12),
                            pad('1.00x', 8),
                            pad(this.benchFmtNum(baseline.processing_tps, 1, ' tok/s'), 12),
                            pad(this.benchFmtNum(baseline.processing_tps, 1, ' tok/s'), 12),
                            pad(this.benchFmtNum(baseline.ttft_ms, 1), 10),
                              "_score_float_topk_",
          topk,
          "_t_",
          tiled_threads);
    } else {
      concatenate(
          kname,
          vec == 1 ? "moe_weighted_sum_" : "moe_weighted_sum_vec",
          vec == 1 ? "" : std::to_string(vec),
          vec == 1 ? "" : "_",
          qwen_type_name(x_sorted.dtype()),
          "_score_float_topk_",
          topk);
    }

    auto lib = d.get_library("omlx_qwen35_prefill_kernels", current_binary_dir());
    auto kernel = d.get_kernel(kname, lib);
    auto& compute_encoder = metal::get_command_encoder(s);
    compute_encoder.set_compute_pipeline_state(kernel);
    compute_encoder.set_input_array(x_sorted, 0);
    compute_encoder.set_input_array(inv_order, 1);
    compute_encoder.set_input_array(scores, 2);
    compute_encoder.set_output_array(out, 3);
    compute_encoder.set_bytes(tokens, 4);
    compute_encoder.set_bytes(D, 5);

    const int threads = use_tiled ? tiled_threads : 256;
    const int total = vec == 1 ? tokens * D : tokens * ((D + vec - 1) / vec);
    MTL::Size group_dims(threads, 1, 1);
    MTL::Size grid_dims(
        use_tiled ? tokens : (total + threads - 1) / threads, 1, 1);
    compute_encoder.dispatch_threadgroups(grid_dims, group_dims);
  }

  DEFINE_NAME(Qwen35MoeWeightedSumPrimitive)
  DEFINE_INPUT_OUTPUT_SHAPE()
  bool is_equivalent(const Primitive& /* other */) const override {
    return true;
  }
  auto state() const {
    return std::make_tuple(nullptr);
  }
};

} // namespace

bool is_nax_available() {
  // Mirror of mlx::core::metal::is_nax_available() (mlx v0.32.0 device.cpp),
  // which libmlx does not export: macOS >= 26.2 and applegpu gen >= 17
  // ('p'-suffix parts need gen >= 18).
  static bool available = []() {
    if (!metal::is_available()) {
      return false;
    }
    bool os_ok = false;
    if (__builtin_available(macOS 26.2, iOS 26.2, tvOS 26.2, visionOS 26.2, *)) {
      os_ok = true;
    }
    if (!os_ok) {
      return false;
    }
    auto& d = metal::device(Device::gpu);
    const auto& arch = d.get_architecture();
    if (arch.empty()) {
      return false;
    }
    const char suffix = arch.back();
    const int gen = d.get_architecture_gen();
    return gen >= (suffix == 'p' ? 18 : 17);
  }();
  return available;
}

bool nax_qmm_kernels_built() {
  static bool built = []() {
    std::error_code ec;
    return std::filesystem::exists(
        std::filesystem::path(current_binary_dir()) /
            (std::string(kNaxMetallibName) + ".metallib"),
        ec);
  }();
  return built;
}

bool nax_qmm_runtime_active() {
  return nax_qmm_runtime_ok.load(std::memory_order_relaxed);
}

array qwen35_fa256_attention(
    const array& q,
    const array& k,
    const array& v,
    float scale,
    bool causal,
    int q_block,
    int k_block,
    int64_t dispatch_budget,
    StreamOrDevice s) {
  for (const auto& tensor : {q, k, v}) {
    if (tensor.ndim() != 4) {
      std::ostringstream msg;
      msg << "[omlx_qwen35_prefill.qwen35_fa256_attention] input with shape "
          << tensor.shape() << " expected rank 4.";
      throw std::invalid_argument(msg.str());
    }
  }
  auto stream = to_stream(s);
  auto final_type = result_type(std::vector<array>{q, k, v});
  if (final_type != float16 && final_type != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_fa256_attention] expected fp16 or "
        << "bf16 inputs, got " << final_type << ".";
    throw std::invalid_argument(msg.str());
  }

  auto q_cast = astype(q, final_type, stream);
  auto k_cast = astype(k, final_type, stream);
  auto v_cast = astype(v, final_type, stream);
  if (Qwen35Fa256AttentionPrimitive::unsupported(
          q_cast, k_cast, v_cast, causal, q_block, k_block, stream)) {
    throw std::invalid_argument(
        "[omlx_qwen35_prefill.qwen35_fa256_attention] unsupported Qwen FA-256 shape.");
  }

  Shape out_shape{
      q_cast.shape(0), q_cast.shape(1), q_cast.shape(2), v_cast.shape(3)};
  std::vector<array> inputs = {q_cast, k_cast, v_cast};
  return array(
      std::move(out_shape),
      final_type,
      std:: and pooled Metal buffers.

    Runs ON the engine's MLX executor thread (thread-local stream +
    serialization with scheduler steps). The bench loads its model fresh
    with everything else unloaded, so clearing the paged cache only drops
    probe blocks — there is no user prefix cache to lose.
    """
    from ..scheduler import _sync_and_clear_cache

    cache = getattr(scheduler, "block_aware_cache", None)
    if cache is not None:
        try:
            cache.clear()
        except Exception as exc:
            logger.debug("Context bench: paged cache clear failed: %s", exc)
    gc.collect()
    _sync_and_clear_cache(getattr(scheduler, "_stream", None))
    # Refresh the cached mlx-active sample so event-loop preflight probes
    # see post-cleanup usage instead of the prefill-peak snapshot.
    try:
        scheduler._current_usage_bytes()
    except Exception as exc:
        logger.debug("Context bench: usage refresh failed: %s", exc)


async def _cleanup_between_probes(engine: Any, scheduler: Any) -> None:
    """Dispatch probe-residue cleanup to the engine's executor and settle."""
    core = _resolve_core(engine)
    executor = getattr(core, "_mlx_executor", None)
    loop = asyncio.get_running_loop()
    for _ in range(2):
        if executor is not None:
            await loop.run_in_executor(executor, _clear_probe_residue, scheduler)
        await asyncio.sleep(0.5)


async def _run_probe_prefill(engine: Any, prompt: str) -> tuple[Any, float]:
    """Prefill the prompt with max_tokens=1; return (final output, seconds).

    Raises PrefillMemoryExceededError / PrefillMemoryAbortedError when the
    memory guard refuses or aborts the probe. With max_tokens=1 the wall
    clock is dominated by the prefill, so callers can derive a prefill
    tok/s from it when the engine does not report prompt_tps.
    """
    started = time.perf_counter()
    last_output = None
    async for output in engine.stream_generate(
        prompt=prompt,
        max_tokens=1,
        temperature=0.0,
        top_p=1.0,
        skip_cache_store=True,
    ):
        last_output = output
    return last_output, time.perf_counter() - started


def next_verify_candidate(
    candidate: int, observed_processed: int, new_boundary: int
) -> int:
    """Conservative retry candidate after a failed verify prefill.

    Physical evidence caps from above: the aborted prefill completed
    ``observed_processed`` tokens before dying, so 90% of that is the
    most a retry should attempt. The re-measured boundary caps too —
    the failure-path cleanup resets the transient tracker first, so the
    re-bisect reflects honest KV/static pricing at the current baseline
    rather than the dead prefill's contaminated last-chunk delta.
    Without evidence (nothing prefilled), halve.
    """
    if observed_processed > 0:
        nxt = min(
            int(observed_processed * _ABORT_EVIDENCE_SAFETY),
            candidate - _APPLY_GRANULARITY,
        )
    else:
        nxt = min(candidate // 2, candidate - _APPLY_GRANULARITY)
    if new_boundary > 0:
        nxt = min(nxt, new_boundary)
    return floor_to_apply_granularity(nxt)


def _reset_transient_tracker(scheduler: Any) -> None:
    """Drop the scheduler's chunk-transient measurements after a failed probe.

    An enforcer-killed prefill leaves a giant last-chunk phys delta in the
    tracker; under speed priority that poisons every subsequent admission
    (a 2048-token charge of several GB), and since rejected probes never
    run a chunk, the poison would never decay within the bench. Resetting
    returns admission to the static + exact-KV estimate until real chunks
    re-seed the EWMA.
    """
    tracker = getattr(scheduler, "_prefill_transient_tracker", None)
    if tracker is not None:
        try:
            tracker.reset()
        except Exception as exc:
            logger.debug("Context bench: tracker reset failed: %s", exc)


async def _relay_prefill_progress(
    run: ContextBenchmarkRun,
    model_id: str,
    attempt: int,
    candidate: int,
    progress_holder: dict,
) ->      modelOptions: vm.modelOptions,
                command: vm.opencodeCommand
            )
            IntegrationRow(
                name: String(localized: "integrations.tool.openclaw",
                             defaultValue: "OpenClaw",
                             comment: "Display name for the OpenClaw integration"),
                modelBinding: vm.bind($vm.openclawModel, save: {
                    Task { await vm.save(.openclawModel, client: client) }
                }),
                modelOptions: vm.modelOptions,
                command: vm.openclawCommand,
                profileBinding: vm.bind($vm.openclawToolsProfile, save: {
                    Task { await vm.save(.openclawToolsProfile, client: client) }
                }),
                profileSublabel: String(localized: "integrations.openclaw.profile_sub",
                                         defaultValue: "Built-in MCP tools the OpenClaw launcher exposes",
                                         comment: "Sublabel for the OpenClaw tools-profile picker")
            )
            IntegrationRow(
                name: String(localized: "integrations.tool.hermes",
                             defaultValue: "Hermes Agent",
                             comment: "Display name for the Hermes Agent integration"),
                modelBinding: vm.bind($vm.hermesModel, save: {
                    Task { await vm.save(.hermesModel, client: client) }
                }),
                modelOptions: vm.modelOptions,
                command: vm.hermesCommand
            )
            IntegrationRow(
                name: String(localized: "integrations.tool.pi",
                             defaultValue: "Pi",
                             comment: "Display name for the Pi integration"),
                modelBinding: vm.bind($vm.piModel, save: {
                    Task { await vm.save(.piModel, client: client) }
                }),
                modelOptions: vm.modelOptions,
                command: vm.piCommand
            )
            IntegrationRow(
                name: String(localized: "integrations.tool.copilot",
                             defaultValue: "Copilot CLI",
                             comment: "Display name for the Copilot CLI integration"),
                modelBinding: vm.bind($vm.copilotModel, save: {
                    Task { await vm.save(.copilotModel, client: client) }
                }),
                modelOptions: vm.modelOptions,
                command: vm.copilotCommand,
                isLast: true
            )
        }
    }
}

/// Per-integration FreeRow: name + model picker on the top half, monospaced
/// launcher command + copy button below. Optional OpenClaw tools-profile
/// popup folds in under the model picker.
private struct IntegrationRow: View {
    let name: String
    let modelBinding: Binding<String>
    let modelOptions: [(String, String)]
    let command: String
    var commandLabel: String? = nil
    var secondaryCommand: String? = nil
    var secondaryCommandLabel: String? = nil
    var profileBinding: Binding<String>? = nil
    var profileSublabel: String? = nil
    var isLast: Bool = false

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        FreeRow(isLast: isLast) {
            VStack(alignment: .leading, spacing: 8) {
                HStack(spacing: 12) {
                    Text(name)
                        .font(.omlxText(13, weight: .medium))
                        .foregroundStyle(theme.text)
                    Spacer(minLength: 12)
                    Popup(
                        selection: modelBinding,
                        width: 220,
                        options: modelOptions
                    )
                }
                if let profileBinding {
                    HStack(spacing: 12) {
                        VStack(alignment: .leading, spacing: 2) {
                            Text(String(localized: "integrations.openclaw.profile_label",
                                        defaultValue: "Tools profile",
                  pad(baseline.e2e_latency_s.toFixed(3), 10),
                        ];
                        lines.push(row.join('  '));
                    }
                    for (const r of results) {
                        const speedup = this.benchGetSpeedup(r);
                        const row = [
                            rpad(r.batch_size + 'x', 8),
                            pad(this.benchFmtNum(r.tg_tps, 1, ' tok/s'), 12),
                            pad(speedup !== null ? speedup.toFixed(2) + 'x' : 'N/A', 8),
                            pad(this.benchFmtNum(r.pp_tps, 1, ' tok/s'), 12),
                            pad(this.benchFmtNum(this.benchPpPerReq(r), 1, ' tok/s'), 12),
                            pad(this.benchFmtNum(r.avg_ttft_ms, 1), 10),
                            pad(r.e2e_latency_s.toFixed(3), 10),
                        ];
                        lines.push(row.join('  '));
                    }
                };

                buildBatchText(
                    'Continuous Batching',
                    this.benchBatchPromptSummary(),
                    this.benchBatchResults
                );

                return lines.join('\n');
            },

            benchCopyText() {
                const text = this.benchBuildText();
                const onSuccess = () => {
                    this.benchCopied = true;
                    setTimeout(() => { this.benchCopied = false; }, 2000);
                };
                if (navigator.clipboard && window.isSecureContext) {
                    navigator.clipboard.writeText(text).then(onSuccess).catch(() => {
                        this._copyFallback(text);
                        onSuccess();
                    });
                } else {
                    this._copyFallback(text);
                    onSuccess();
                }
            },

            async loadBenchDeviceInfo() {
                try {
                    const resp = await fetch('/admin/api/device-info');
                    if (resp.ok) {
                        this.benchDeviceInfo = await resp.json();
                    }
                } catch (err) {
                    console.error('Failed to load device info:', err);
                }
            },

            async loadBenchState() {
                // Discover an in-progress throughput run on tab/page load so
                // a second tab (or a refresh) can attach to its SSE stream
                // and replay the run's full event history.
                //
                // Three cases:
                //   1. No active run → clear any stale banner state.
                //   2. Active run, this tab is already attached → no-op.
                //   3. Active run, this tab is fresh → auto-attach.
                //   4. Active run, this tab is displaying a *different*
                //      completed bench → show banner; let the user decide
                //      whether to clobber their result view.
                try {
                    const resp = await fetch('/admin/api/bench/active');
                    if (!resp.ok) return;
                    const data = await resp.json();

                    if (!data.running || !data.bench_id) {
                        this.benchOtherActive = null;
                        return;
                    }

                    // Already attached to this bench — nothing to do.
                    if (this.benchBenchId === data.bench_id && this.benchEventSource) {
                        return;
                    }

                    // We have completed results from a DIFFERENT bench on
                    // screen — don't silently swap them out. Show a banner
                    // so the user can explicitly accept the new bench.
                    const hasStaleResults = !this.benchRunning
                        && this.benchBenchId
                        && this.benchBenchId !== data.bench_id
                        && (this.benchSingleResults.length > 0
                            || this.benchBatchResults.length > 0);
                 make_shared<Qwen35Fa256AttentionPrimitive>(
          stream, scale, causal, q_block, k_block, dispatch_budget),
      std::move(inputs));
}

array qwen35_q_affine_qmm_t(
    const array& x,
    const array& weight,
    const array& scales,
    const array& biases,
    int bits,
    int variant,
    bool use_nax,
    int nax_variant,
    int group_size,
    StreamOrDevice s) {
  (void)qwen_q_affine_variant(variant);
  if (!qwen_q_affine_bits_supported(bits)) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_q" << bits
        << "_affine_qmm_t] unsupported bits.";
    throw std::invalid_argument(msg.str());
  }
  if (group_size != 64 && group_size != 128) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_q" << bits
        << "_affine_qmm_t] unsupported group_size " << group_size << ".";
    throw std::invalid_argument(msg.str());
  }

  if (x.ndim() < 2 || weight.ndim() != 2 || scales.ndim() != 2 ||
      biases.ndim() != 2) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_q" << bits
        << "_affine_qmm_t] expected x [...,K], packed weight, "
        << "scales/biases [N,K/" << group_size << "], got " << x.shape()
        << ", " << weight.shape() << ", " << scales.shape() << ", "
        << biases.shape() << ".";
    throw std::invalid_argument(msg.str());
  }

  const int K = x.shape(-1);
  const int N = weight.shape(0);
  if (K <= 0 || N <= 0 || K % group_size != 0 ||
      !qwen_q_affine_packed_shape_matches(weight.shape(1), K, bits) ||
      scales.shape(0) != N || scales.shape(1) != K / group_size ||
      biases.shape() != scales.shape()) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_q" << bits
        << "_affine_qmm_t] incompatible shapes: " << x.shape() << ", "
        << weight.shape() << ", " << scales.shape() << ", " << biases.shape()
        << ".";
    throw std::invalid_argument(msg.str());
  }
  if (x.dtype() != float16 && x.dtype() != bfloat16) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_q" << bits
        << "_affine_qmm_t] expected float16 or bfloat16 input, got "
        << x.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (weight.dtype() != uint32 || scales.dtype() != x.dtype() ||
      biases.dtype() != x.dtype()) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_q" << bits
        << "_affine_qmm_t] expected uint32 weight and scale/bias dtype "
        << x.dtype() << ", got " << weight.dtype() << ", " << scales.dtype()
        << ", " << biases.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  if (Qwen35QAffineQmmTPrimitive::unsupported(
          x, weight, scales, biases, bits, variant, group_size, stream)) {
    throw std::invalid_argument(
        "[omlx_qwen35_prefill.qwen35_q_affine_qmm_t] unsupported shape.");
  }

  // NAX only supports group_size=64; demote rather than throwing when the
  // NAX tile does not fit or the runtime lacks tensor units / the NAX metallib.
  bool nax = use_nax && group_size == 64 && is_nax_available() &&
      nax_qmm_kernels_built() &&
      nax_qmm_runtime_ok.load(std::memory_order_relaxed);
  if (nax) {
    const auto nax_cfg = qwen_q_affine_nax_variant(nax_variant);
    if (K % nax_cfg.bk != 0 || N % nax_cfg.bn != 0) {
      nax = false;
    }
  }

  Shape out_shape = x.shape();
  out_shape.back() = N;
  std::vector<array> inputs = {x, weight, scales, biases};
  return array(
      std::move(out_shape),
      x.dtype(),
      std::make_shared<Qwen35QAffineQmmTPrimitive>(
          stream, bits, variant, nax, nax_variant, group_size),
      std::move(inputs));
}

array qwen35_q2_affine_qmm_t(
    const array& x,
    const array& weight,
    const array& scales,
    const array& biases,
    int variant,
    bool use_nax,
    int nax_variant,
    int group_size,
    StreamOrDevice s) {
  return qwen35_q_affine_qmm_t(
      x, weight, scales, biases, 2, variant, use_nax, nax_variant, group_size, s);
}

array qwen35_q4_affine_qmm_t(
    const array& x,
    const None:
    """Poll the global prefill tracker and mirror % into verify progress.

    Also records the last seen processed-token count into
    ``progress_holder`` so a failed attempt can derive its retry
    candidate from where the prefill actually died.
    """
    tracker = get_prefill_tracker()
    last_emitted = -1.0
    while True:
        await asyncio.sleep(1.5)
        entries = tracker.get_model_progress(model_id)
        if not entries:
            continue
        entry = entries[0]
        progress_holder["processed"] = max(
            int(progress_holder.get("processed", 0)), int(entry["processed"])
        )
        total = max(1, entry["total"])
        fraction = entry["processed"] / total
        if fraction - last_emitted < 0.01:
            continue
        last_emitted = fraction
        message = (
            f"Verify prefill {candidate:,} tokens (attempt {attempt}): "
            f"{entry['processed']:,}/{entry['total']:,}"
        )
        details = []
        speed = entry.get("speed")
        if speed:
            details.append(f"{speed:,.0f} tok/s")
        eta = entry.get("eta")
        if eta is not None:
            details.append(f"~{int(eta)}s left")
        if details:
            message += f" ({', '.join(details)})"
        await _progress(run, "verify", fraction, message)


async def run_context_benchmark(run: ContextBenchmarkRun, engine_pool: Any) -> None:
    """Execute a context benchmark run.

    Phases: prepare (unload all → load target) → calibrate → estimate
    (bisect admission) → verify (real prefill, step down on abort) →
    apply (write max_context_window) → cleanup (unload).
    """
    request = run.request
    overall_start = time.perf_counter()

    try:
        # Phase 1: prepare — unload everything, load the target model.
        loaded_ids = engine_pool.get_loaded_model_ids()
        if loaded_ids:
            await _progress(
                run, "prepare", 0.1, f"Unloading {len(loaded_ids)} model(s)..."
            )
            for model_id in loaded_ids:
                try:
                    await engine_pool._unload_engine(model_id)
                    logger.info("Context bench: unloaded %s", model_id)
                except Exception as exc:
                    logger.warning(
                        "Context bench: failed to unload %s: %s", model_id, exc
                    )

        await _progress(run, "prepare", 0.4, f"Loading {request.model_id}...")
        engine = await engine_pool.get_engine(request.model_id)
        logger.info("Context bench: loaded %s", request.model_id)

        scheduler = _resolve_scheduler(engine)
        if scheduler is None:
            raise RuntimeError(
                "This model's engine does not expose a scheduler, so the "
                "context benchmark cannot probe its admission boundary. "
                "Disable speculative engine features (e.g. DFlash) for this "
                "model and retry."
            )
        if not _guard_ready(scheduler):
            raise RuntimeError(
                "The prefill memory guard is disabled, so there is no "
                "admission boundary to measure. Enable Memory Guard and "
                "retry."
            )

        entry = engine_pool.get_entry(request.model_id)
        native = getattr(entry, "model_context_length", None) or 0
        cap = request.target_tokens
        cap_source = "target"
        if 0 < native < cap:
            cap = native
            cap_source = "native"

        # Phase 2: calibrate — JIT warmup, then one real mid-size prefill
        # to seed the transient tracker EWMA and the GDN fixed-state probe.
        tokenizer = engine.tokenizer
        await _progress(run, "calibrate", 0.1, "Warming up (JIT compile)...")
        async for _ in engine.stream_generate(
            prompt=_generate_prompt(tokenizer, 32),
            max_tokens=8,
            temperature=0.0,
            skip_cache_store=True,
        ):
            pass

        calibration_tokens = min(_CALIBRATION_TOKENS, max(1024, cap // 2))
        await _p                       comment: "Row label for the OpenClaw tools-profile picker"))
                                .font(.omlxText(12))
                                .foregroundStyle(theme.textSecondary)
                            if let profileSublabel {
                                Text(profileSublabel)
                                    .font(.omlxText(11))
                                    .foregroundStyle(theme.textTertiary)
                            }
                        }
                        Spacer(minLength: 12)
                        Popup(
                            selection: profileBinding,
                            width: 160,
                            options: [
                                ("minimal",   String(localized: "integrations.openclaw.profile.minimal",
                                                     defaultValue: "Minimal",
                                                     comment: "OpenClaw tools profile option: minimal")),
                                ("coding",    String(localized: "integrations.openclaw.profile.coding",
                                                     defaultValue: "Coding",
                                                     comment: "OpenClaw tools profile option: coding")),
                                ("messaging", String(localized: "integrations.openclaw.profile.messaging",
                                                     defaultValue: "Messaging",
                                                     comment: "OpenClaw tools profile option: messaging")),
                                ("full",      String(localized: "integrations.openclaw.profile.full",
                                                     defaultValue: "Full",
                                                     comment: "OpenClaw tools profile option: full")),
                            ]
                        )
                    }
                }
                if let secondaryCommand {
                    VStack(alignment: .leading, spacing: 6) {
                        CommandBlock(command: command, caption: commandLabel)
                        CommandBlock(command: secondaryCommand, caption: secondaryCommandLabel)
                    }
                } else {
                    CommandBlock(command: command, caption: commandLabel)
                }
            }
        }
    }
}

// MARK: - MCP

/// Path to an MCP server config file consumed by every integration launcher
/// (Claude Code, OpenClaw, Hermes, …). Lives at the bottom of Integrations
/// because it's a shared resource — putting it under any one integration
/// would mislead.
private struct MCPSection: View {
    @Bindable var vm: IntegrationsScreenVM
    let client: OMLXClient

    var body: some View {
        SectionHeader(
            String(localized: "integrations.section.mcp",
                   defaultValue: "MCP",
                   comment: "Section header for the MCP config path row"),
            subtitle: String(localized: "integrations.section.mcp.sub",
                             defaultValue: "Path to an MCP server config file. Shared across all integration launchers.",
                             comment: "Subtitle for the MCP section")
        )

        ListGroup {
            Row(
                label: String(localized: "integrations.mcp.config_path",
                              defaultValue: "Config Path",
                              comment: "Row label for the MCP config path input"),
                sublabel: String(localized: "integrations.mcp.config_path.sub",
                                 defaultValue: "Absolute path to an MCP config JSON. Leave blank to disable.",
                                 comment: "Sublabel describing the MCP config path field"),
                isLast: true
            ) {
                TextInput(
                    text: $vm.mcpConfigPath,
                    placeholder: "/path/to/mcp.json",
                    mono: true,
                    width: 320
                )
            }
        }
        HStack   if (hasStaleResults) {
                        this.benchOtherActive = {
                            bench_id: data.bench_id,
                            model_id: data.model_id,
                            context_profile: data.context_profile || 'code_python',
                            force_lm_engine: !!data.force_lm_engine,
                            external: !!data.external,
                        };
                        return;
                    }

                    // Fresh slate: attach.
                    this.benchBenchId = data.bench_id;
                    this._restoreBenchRunSource(data);
                    this.benchRunning = true;
                    this.benchOtherActive = null;
                    this.connectBenchSSE(data.bench_id);
                } catch (err) {
                    console.error('Failed to load bench state:', err);
                }
            },

            // Restore the config UI from an active run discovered via
            // /api/bench/active. External model ids aren't in the local
            // dropdown, so the external flag drives which controls light up.
            _restoreBenchRunSource(data) {
                this.benchContextProfile = data.context_profile || 'code_python';
                if (data.external) {
                    this.benchExternalEnabled = true;
                    this.benchRunExternal = {
                        // base_url is intentionally not exposed by the API;
                        // fall back to this browser's stored setting.
                        base_url: this.externalBaseUrl.trim(),
                        model: data.model_id,
                    };
                } else {
                    this.benchModelId = data.model_id;
                    this.benchForceLmEngine = !!data.force_lm_engine;
                    this.benchExternalEnabled = false;
                    this.benchRunExternal = null;
                }
            },

            benchContextLabel(profile) {
                const keys = {
                    code_python: 'bench.config.context.code_python',
                    code_mixed: 'bench.config.context.code_mixed',
                    novel_ko: 'bench.config.context.novel_ko',
                    novel_en: 'bench.config.context.novel_en',
                    novel_ja: 'bench.config.context.novel_ja',
                };
                return window.t(keys[profile] || keys.code_python);
            },

            // User clicked "View live" on the banner — clear the stale
            // result display, attach to the active run. The replay-on-
            // subscribe stream re-delivers every event so the new bench
            // populates its table from the start.
            acceptOtherBench() {
                if (!this.benchOtherActive) return;
                const other = this.benchOtherActive;
                this.benchOtherActive = null;
                this.benchBenchId = other.bench_id;
                this._restoreBenchRunSource(other);
                this.benchRunning = true;
                this.benchSingleResults = [];
                this.benchBatchResults = [];
                this.benchUploadResults = [];
                this.benchUploadDone = null;
                this.benchUploadSkipped = null;
                this.benchUploadFlags = [];
                this.benchProgress = null;
                this.benchError = '';
                this.connectBenchSSE(other.bench_id);
            },

            dismissOtherBench() {
                // Hide for now; the banner reappears next loadBenchState if
                // the run is still active. Use case: user wants to keep
                // reviewing their previous result for a moment.
                this.benchOtherActive = null;
            },

            // Bench sub-tab
            setBenchTab(tab) {
                if (!DASHBOARD_BENCH_TABS.has(tab)) return;
                this.benchTab = tab;
                this.mainTab = 'bench';
                this.syncTabStateToUrl();
                if (tab === 'throughput') {
           array& weight,
    const array& scales,
    const array& biases,
    int variant,
    bool use_nax,
    int nax_variant,
    int group_size,
    StreamOrDevice s) {
  return qwen35_q_affine_qmm_t(
      x, weight, scales, biases, 4, variant, use_nax, nax_variant, group_size, s);
}

array qwen35_q5_affine_qmm_t(
    const array& x,
    const array& weight,
    const array& scales,
    const array& biases,
    int variant,
    bool use_nax,
    int nax_variant,
    int group_size,
    StreamOrDevice s) {
  return qwen35_q_affine_qmm_t(
      x, weight, scales, biases, 5, variant, use_nax, nax_variant, group_size, s);
}

array qwen35_q6_affine_qmm_t(
    const array& x,
    const array& weight,
    const array& scales,
    const array& biases,
    int variant,
    bool use_nax,
    int nax_variant,
    int group_size,
    StreamOrDevice s) {
  return qwen35_q_affine_qmm_t(
      x, weight, scales, biases, 6, variant, use_nax, nax_variant, group_size, s);
}

array qwen35_q8_affine_qmm_t(
    const array& x,
    const array& weight,
    const array& scales,
    const array& biases,
    int variant,
    bool use_nax,
    int nax_variant,
    int group_size,
    StreamOrDevice s) {
  return qwen35_q_affine_qmm_t(
      x, weight, scales, biases, 8, variant, use_nax, nax_variant, group_size, s);
}

array qwen35_moe_weighted_sum(
    const array& x_sorted,
    const array& inv_order,
    const array& scores,
    StreamOrDevice s) {
  if (x_sorted.ndim() != 3 || x_sorted.shape(-2) != 1) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_moe_weighted_sum] expected "
        << "x_sorted shape [N, 1, D], got " << x_sorted.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (scores.ndim() < 2) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_moe_weighted_sum] expected scores "
        << "rank >= 2, got " << scores.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (inv_order.ndim() != 1 || inv_order.dtype() != uint32) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_moe_weighted_sum] expected uint32 "
        << "inv_order rank 1, got " << inv_order.shape() << " dtype "
        << inv_order.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }
  const int topk = scores.shape(-1);
  const int64_t routed_rows = scores.size();
  const int D = x_sorted.shape(-1);
  if (x_sorted.shape(0) != routed_rows || inv_order.size() != routed_rows) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_moe_weighted_sum] incompatible "
        << "shapes: " << x_sorted.shape() << ", " << inv_order.shape()
        << ", " << scores.shape() << ".";
    throw std::invalid_argument(msg.str());
  }
  if (topk <= 0 || D <= 0) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_moe_weighted_sum] invalid topk or "
        << "hidden dim: topk=" << topk << ", D=" << D << ".";
    throw std::invalid_argument(msg.str());
  }
  if (!issubdtype(x_sorted.dtype(), floating)) {
    std::ostringstream msg;
    msg << "[omlx_qwen35_prefill.qwen35_moe_weighted_sum] expected floating "
        << "x_sorted, got " << x_sorted.dtype() << ".";
    throw std::invalid_argument(msg.str());
  }

  auto stream = to_stream(s);
  std::vector<array> inputs = {x_sorted, inv_order, scores};
  Shape out_shape = scores.shape();
  out_shape.pop_back();
  out_shape.push_back(D);
  if (Qwen35MoeWeightedSumPrimitive::unsupported(
          x_sorted, inv_order, scores, stream)) {
    throw std::invalid_argument(
        "[omlx_qwen35_prefill.qwen35_moe_weighted_sum] unsupported Qwen shape.");
  }
  return array(
      std::move(out_shape),
      x_sorted.dtype(),
      std::make_shared<Qwen35MoeWeightedSumPrimitive>(stream),
      std::move(inputs));
}

} // namespace omlx::qwen35_prefill_kernels


# ===== FILE: omlx/custom_kernels/bonsai/csrc/bonsai_kernels.h =====

// Copyright © 2026 oMLX contributors
// SPDX-License-Identifier: Apache-2.0
//
// Bonsai 1-bit / 2-bit affine quantized decode kernels.
//
// These wrap Metal kernels ported from the Bonrogress(
            run,
            "calibrate",
            0.4,
            f"Calibration prefill ({calibration_tokens:,} tokens)...",
        )
        try:
            await _run_probe_prefill(
                engine, _generate_prompt(tokenizer, calibration_tokens)
            )
        except (PrefillMemoryExceededError, PrefillMemoryAbortedError) as exc:
            raise RuntimeError(
                f"Not enough memory to prefill even {calibration_tokens:,} "
                f"tokens on this machine: {exc}"
            ) from exc
        await _cleanup_between_probes(engine, scheduler)

        # Phase 3: estimate — bisect the deterministic admission boundary.
        await _progress(run, "estimate", 0.3, "Estimating admission boundary...")
        fits = _make_fits(scheduler)
        boundary = bisect_admission(fits, 1024, cap)
        if floor_to_apply_granularity(boundary) < _MIN_USEFUL_TOKENS:
            raise RuntimeError(
                "Admission boundary is below 2k tokens — not enough free "
                "memory to serve a usable context for this model."
            )
        logger.info(
            "Context bench: admission boundary %d tokens (cap %d, %s)",
            boundary,
            cap,
            cap_source,
        )

        # Phase 4: verify — real prefill at the floored candidate. On a
        # mid-prefill abort, one conservative retry sized from where the
        # first prefill actually died (90% of its processed tokens). An
        # INSTANT admission rejection (0 tokens processed — current drifted
        # between the bisection and the probe) costs no GPU time and does
        # not consume a real-prefill attempt; it just re-bisects with the
        # fresh usage and retries, bounded by the spin cap.
        candidate = floor_to_apply_granularity(min(boundary, cap))
        verified = 0
        verified_prompt_tokens = 0
        verify_prefill_tps = 0.0
        attempts = 0
        spins = 0
        had_abort = False
        while spins < _MAX_VERIFY_SPINS:
            spins += 1
            attempt_no = attempts + 1
            await _progress(
                run,
                "verify",
                0.0,
                f"Verify prefill {candidate:,} tokens (attempt {attempt_no})...",
            )
            progress_holder: dict = {}
            relay = asyncio.create_task(
                _relay_prefill_progress(
                    run, request.model_id, attempt_no, candidate, progress_holder
                )
            )
            try:
                output, probe_seconds = await _run_probe_prefill(
                    engine, _generate_prompt(tokenizer, candidate)
                )
            except (PrefillMemoryExceededError, PrefillMemoryAbortedError) as exc:
                observed = int(progress_holder.get("processed", 0))
                instant_reject = (
                    not isinstance(exc, PrefillMemoryAbortedError) and observed == 0
                )
                if not instant_reject:
                    attempts += 1
                    had_abort = True
                logger.info(
                    "Context bench: verify failed at %d tokens "
                    "(attempt %d, %d processed%s): %s",
                    candidate,
                    attempt_no,
                    observed,
                    ", instant reject" if instant_reject else "",
                    exc,
                )
                if attempts >= _MAX_VERIFY_ATTEMPTS:
                    raise RuntimeError(
                        f"Verification failed {_MAX_VERIFY_ATTEMPTS} times — "
                        f"the machine could not complete a prefill at the "
                        f"measured sizes. Raise the Memory Guard ceiling or "
                        f"pick a smaller target and rerun."
                    ) from exc
                await _cleanup_between_probes(engine, scheduler)
                # Drop the dead prefill's contaminated transient sample so
                # the re-bisect prices the next candidate honestly.
                _reset_t {
            Spacer()
            Button(String(localized: "integrations.mcp.apply",
                          defaultValue: "Apply",
                          comment: "Apply button for the MCP config path")) {
                Task { await vm.save(.mcpConfig, client: client) }
            }
            .buttonStyle(.omlx(.primary))
            .disabled(!vm.hasPendingMCPChanges)
        }
        .padding(.horizontal, 18)
        .padding(.top, 6)
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/LogsScreen.swift =====

// PR 7 — Logs screen. Tails `/admin/api/logs` and renders the result in a
// monospaced ScrollView with a Lines popup, file selector, refresh button
// and copy-all. The view auto-refreshes every 5 s while visible.

import SwiftUI
import AppKit

struct LogsScreen: View {
    @Environment(AppServices.self) private var services
    @State private var vm = LogsScreenVM()

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            SectionHeader(String(localized: "logs.section.title",
                                  defaultValue: "Server Logs",
                                  comment: "Section header above the log tail pane on the Logs screen"),
                          subtitle: vm.subtitle) {
                Button(String(localized: "common.copy",
                              defaultValue: "Copy",
                              comment: "Button label to copy the visible log text to the pasteboard")) {
                    vm.copyToPasteboard()
                }
                              .buttonStyle(.omlx(.normal, size: .small))
                              .disabled(vm.lines == 0 || vm.logText.isEmpty)
            }

            if vm.availableFiles.count > 1 {
                ListGroup {
                    Row(label: String(localized: "logs.row.file.label",
                                      defaultValue: "Log file",
                                      comment: "Row label for the log file selector popup on the Logs screen"),
                        isLast: true) {
                        Popup(
                            selection: $vm.selectedFile,
                            width: 220,
                            options: vm.fileOptions
                        )
                    }
                }
            }

            LogPane(text: vm.logText, isEmpty: vm.logText.isEmpty, isLoading: vm.isLoading)
                .padding(.horizontal, 14)
                .padding(.top, vm.availableFiles.count > 1 ? 0 : 6)
                .padding(.bottom, 8)
                .frame(maxWidth: .infinity, maxHeight: .infinity)

            if let error = vm.lastError {
                Text(error)
                    .font(.omlxText(11))
                    .foregroundStyle(.red)
                    .padding(.horizontal, 18)
                    .padding(.top, 4)
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
        .toolbar {
            ToolbarItemGroup(placement: .primaryAction) {
                logLinesPicker
                reloadButton
            }
        }
        .task(id: vm.refreshKey) {
            await vm.start(client: services.client)
        }
        .onChange(of: vm.lines) { _, _ in vm.bumpRefreshKey() }
        .onChange(of: vm.selectedFile) { _, _ in vm.bumpRefreshKey() }
        .onDisappear { vm.stop() }
    }

    @ViewBuilder
    private var logLinesPicker: some View {
        let lineOptions = [
            (100,
             String(localized: "logs.lines.100",
                    defaultValue: "Last 100",
                    comment: "Popup option to show the most recent 100 log lines")),
            (500,
             String(localized: "logs.lines.500",
                    defaultValue: "Last 500",
                    comment: "Popup option to show the most recent 500 log lines")),
            (1000,
             String(localized: "logs.lines.1000",
                    defaultValue: "Last 1,000",
                    comment: "Popup option to show the most recent 1,000 log line          this.loadBenchDeviceInfo();
                    this.loadBenchState();
                }
                if (tab === 'context') {
                    this.loadCtxBenchState();
                    // The priority segment mirrors the global setting —
                    // refresh in case it changed on the Settings tab or in
                    // another window.
                    this.loadGlobalSettings();
                }
            },

            // Accuracy benchmark functions

            async loadAccState() {
                // Load accumulated results + queue status from server (page load / tab switch)
                try {
                    const resp = await fetch('/admin/api/bench/accuracy/results');
                    if (resp.ok) {
                        const data = await resp.json();
                        this.accAllResults = (data.results || []).map(r => ({ ...r, _showCategories: false }));
                        this.accRunning = data.running || false;
                        this.accCurrentModel = data.current_model || '';
                        if (data.current_bench_id && data.running) {
                            this.accCurrentBenchId = data.current_bench_id;
                            this.connectAccSSE(data.current_bench_id);
                        }
                    }
                } catch (err) {
                    console.error('Failed to load accuracy state:', err);
                }
                await this.loadAccQueueStatus();
            },

            async loadAccQueueStatus() {
                try {
                    const resp = await fetch('/admin/api/bench/accuracy/queue/status');
                    if (resp.ok) {
                        const data = await resp.json();
                        this.accQueue = data.queue || [];
                        this.accRunning = data.running || false;
                        this.accCurrentModel = data.current_model || '';
                        if (data.current_bench_id) {
                            this.accCurrentBenchId = data.current_bench_id;
                        }
                        // Restore last progress for reconnect
                        if (data.last_progress && data.running) {
                            this.accProgress = data.last_progress;
                        }
                    }
                } catch (err) {
                    console.error('Failed to load queue status:', err);
                }
            },

            async addToAccQueue() {
                let externalRequest = null;
                if (this.accExternalEnabled) {
                    if (!this.externalConfigValid()) {
                        this.accError = window.t('js.error.external_endpoint_required');
                        return;
                    }
                    try {
                        externalRequest = this.accuracyExternalRequestBody();
                    } catch (err) {
                        this.accError = err.message;
                        return;
                    }
                } else if (!this.accModelId) {
                    return;
                }
                const selected = Object.entries(this.accBenchmarks)
                    .filter(([_, v]) => v)
                    .map(([k]) => k);
                if (selected.length === 0) return;

                this.accError = '';

                try {
                    const resp = await fetch('/admin/api/bench/accuracy/queue/add', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            model_id: this.accExternalEnabled ? this.externalModel.trim() : this.accModelId,
                            benchmarks: Object.fromEntries(
                                selected.map(k => [k, this.accSampleSizes[k]])
                            ),
                            batch_size: this.accBatchSize,
                            enable_thinking: this.accExternalEnabled ? false : thisai MLX fork
// (github.com/PrismML-Eng/Bonsai-demo) which added:
//   - 1-bit qmv_fast support to mlx's quantized.h
//   - qmv_wide: small-batch (M=2..5) reuse kernel for 1/2-bit affine
//   - spec_decode_verify: fused greedy speculative-decode verify

#pragma once

#include "mlx/array.h"
#include "mlx/stream.h"
#include "mlx/utils.h"

#include <optional>

namespace omlx::bonsai_kernels {

using mlx::core::array;
using mlx::core::StreamOrDevice;

// ---------------------------------------------------------------------------
// 1-bit affine qmv_fast (M = 1)
// ---------------------------------------------------------------------------
// x      : [..., K]         float16 or bfloat16
// w      : [..., N, K/8]    packed 1-bit weights (uint8)
// scales : [..., N, K/gs]   float16 or bfloat16
// biases : [..., N, K/gs]   float16 or bfloat16
// Returns [..., N].
array bonsai_q1_affine_qmv(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s = {});

// ---------------------------------------------------------------------------
// 2-bit affine qmv_fast (M = 1)
// ---------------------------------------------------------------------------
// Same layout as bonsai_q1_affine_qmv but bits=2 (w has K/4 packed uint8 per row).
array bonsai_q2_affine_qmv(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s = {});

// ---------------------------------------------------------------------------
// 1-bit affine qmv_wide (M = 2..5)
// ---------------------------------------------------------------------------
// Same layout as bonsai_q1_affine_qmv but uses the wide kernel for small
// batch, amortising weight loads across all M vectors.
// Caller is responsible for the routing decision (use_qmv_wide gate).
array bonsai_q1_affine_qmv_wide(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s = {});

// ---------------------------------------------------------------------------
// 2-bit affine qmv_wide (M = 2..5)
// ---------------------------------------------------------------------------
// Same layout as above but bits=2 (w has K/4 packed uint8 per row).
// Caller is responsible for the routing decision (use_qmv_wide gate).
array bonsai_q2_affine_qmv_wide(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s = {});

// ---------------------------------------------------------------------------
// spec_decode_verify
// ---------------------------------------------------------------------------
// draft  : [B, K]     int32 — drafted token ids
// target : [B, K+1]   int32 — target argmax tokens (caller runs argmax first)
// Returns {n_accepted [B], committed [B, K+1]}.
array bonsai_q1_affine_qmv_sym(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s = {});

array bonsai_q2_affine_qmv_sym(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s = {});

array bonsai_q1_affine_qmv_wide_sym(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s = {});

array bonsai_q2_affine_qmv_wide_sym(
    const array& x,
    const array& w,
    const array& scales,
    const array& biases,
    StreamOrDevice s = {});

// ---------------------------------------------------------------------------
// t5: base-3 ternary qmv (Identity I-D, ~1.585 bpw)
// ---------------------------------------------------------------------------
// x      : [..., K]                float16 or bfloat16
// w      : [..., N, n_groups*bpg]  uint8 t5 bytes (bpg=26 for gs=128, 13 for gs=64)
// scales : [..., N, n_groups]      float16 or bfloat16 (no biases — always symmetric)
// Returns [..., N].
array bonsai_t5_qmv(
    const array& x,
    const array& w,
    const array& scales,
    StreamOrDevice s = {});

array bonsai_t5_qmv_wide(
    const array& x,
    const array& w,
    const arrransient_tracker(scheduler)
                new_boundary = bisect_admission(fits, 1024, candidate)
                if instant_reject:
                    # Free retry: one grain below the freshly measured
                    # boundary.
                    candidate = floor_to_apply_granularity(
                        min(new_boundary, candidate - _APPLY_GRANULARITY)
                    )
                else:
                    candidate = next_verify_candidate(candidate, observed, new_boundary)
                if candidate < _MIN_USEFUL_TOKENS:
                    raise RuntimeError(
                        "Verification kept failing above the 2k floor — "
                        "not enough stable memory for a usable context."
                    ) from exc
                continue
            finally:
                relay.cancel()
            attempts += 1
            verified = candidate
            verified_prompt_tokens = int(
                getattr(output, "prompt_tokens", 0) or candidate
            )
            # Prefill speed of the successful verify: prefer the engine's
            # own figure, fall back to the probe wall clock (max_tokens=1,
            # so it is essentially all prefill).
            verify_prefill_tps = float(getattr(output, "prompt_tps", 0.0) or 0.0)
            if verify_prefill_tps <= 0 and probe_seconds > 0:
                verify_prefill_tps = verified_prompt_tokens / probe_seconds
            break
        if verified == 0:
            raise RuntimeError(
                "Verification did not converge within the retry budget. "
                "Raise the Memory Guard ceiling or pick a smaller target "
                "and rerun."
            )

        # Extension probes: the verified value came straight from the
        # analytic boundary (clean first-try completion, memory-bound).
        # Near the ceiling the boundary can be conservative, so keep
        # probing at 1.2x steps until the cap is reached or a probe
        # fails. Every probe re-passes the live admission gate at the
        # settled baseline, and only COMPLETED prefills raise the value;
        # the first rejection or abort ends the climb and keeps the last
        # completed size.
        extended = False
        extension_aborted = False
        while not had_abort and verified < floor_to_apply_granularity(cap):
            ext_target = min(
                ceil_to_apply_granularity(int(verified * _EXTENSION_FACTOR)), cap
            )
            if ext_target <= verified:
                break
            await _cleanup_between_probes(engine, scheduler)
            await _progress(
                run,
                "verify",
                0.98,
                f"Extension probe {ext_target:,} tokens " f"({_EXTENSION_FACTOR}x)...",
            )
            progress_holder = {}
            relay = asyncio.create_task(
                _relay_prefill_progress(
                    run,
                    request.model_id,
                    attempts + 1,
                    ext_target,
                    progress_holder,
                )
            )
            try:
                output, probe_seconds = await _run_probe_prefill(
                    engine, _generate_prompt(tokenizer, ext_target)
                )
            except (
                PrefillMemoryExceededError,
                PrefillMemoryAbortedError,
            ) as exc:
                observed = int(progress_holder.get("processed", 0))
                if observed > 0 or isinstance(exc, PrefillMemoryAbortedError):
                    attempts += 1
                    extension_aborted = True
                logger.info(
                    "Context bench: extension probe failed at %d tokens "
                    "(%d processed): %s",
                    ext_target,
                    observed,
                    exc,
                )
                await _cleanup_between_probes(engine, scheduler)
                _reset_transient_tracker(scheduler)
                break
            else:
                attempts += 1
s")),
            (5000,
             String(localized: "logs.lines.5000",
                    defaultValue: "Last 5,000",
                    comment: "Popup option to show the most recent 5,000 log lines")),
            (20000,
             String(localized: "logs.lines.20000",
                    defaultValue: "Last 20,000",
                    comment: "Popup option to show the most recent 20,000 log lines")),
        ]

        Popup(
            selection: $vm.lines,
            width: 110,
            options: lineOptions
        )
    }

    @ViewBuilder
    private var reloadButton: some View {
        Button {
            Task { await vm.reload() }
        } label: {
            Image(systemName: "arrow.clockwise")
        }
        .disabled(vm.isLoading)
    }
}

// MARK: - Log pane

private struct LogPane: View {
    let text: String
    let isEmpty: Bool
    let isLoading: Bool

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        ZStack {
            // NSTextView handles tens of thousands of lines effortlessly,
            // unlike SwiftUI's Text which lays out the entire string up
            // front on every render. The bridge below keeps selection,
            // smooth scrolling, and Cmd+A intact.
            LogTextView(
                text: text,
                fgColor: NSColor(theme.text),
                bgColor: NSColor(theme.codeBg)
            )
            if isEmpty && !isLoading {
                Text(String(localized: "logs.empty",
                            defaultValue: "No log entries.",
                            comment: "Empty-state text shown inside the log pane when the server has no log entries"))
                    .font(.omlxText(12))
                    .foregroundStyle(theme.textTertiary)
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding(.vertical, 36)
            }
        }
        .frame(minHeight: 360, idealHeight: 480, maxHeight: .infinity)
        .background(theme.codeBg)
        .clipShape(RoundedRectangle(cornerRadius: theme.cornerRadius, style: .continuous))
        .overlay(
            RoundedRectangle(cornerRadius: theme.cornerRadius, style: .continuous)
                .strokeBorder(theme.groupBorder, lineWidth: 0.5)
        )
    }
}

/// AppKit-backed monospaced text view wrapped in a scroll view. Reads its
/// content from `text` and follows the bottom only when the user is already
/// pinned there — preserving the scroll position when they've scrolled up
/// to inspect a specific entry.
private struct LogTextView: NSViewRepresentable {
    let text: String
    let fgColor: NSColor
    let bgColor: NSColor

    func makeNSView(context: Context) -> NSScrollView {
        let scroll = NSTextView.scrollableTextView()
        scroll.hasVerticalScroller = true
        scroll.hasHorizontalScroller = false
        scroll.autohidesScrollers = true
        scroll.borderType = .noBorder
        scroll.drawsBackground = false

        guard let textView = scroll.documentView as? NSTextView else {
            return scroll
        }
        textView.isEditable = false
        textView.isSelectable = true
        textView.isRichText = false
        textView.allowsUndo = false
        textView.usesFindBar = true
        textView.isIncrementalSearchingEnabled = true
        textView.drawsBackground = true
        textView.backgroundColor = bgColor
        textView.textContainerInset = NSSize(width: 12, height: 10)
        textView.font = NSFont.monospacedSystemFont(ofSize: 11.5, weight: .regular)
        textView.textColor = fgColor
        textView.isAutomaticQuoteSubstitutionEnabled = false
        textView.isAutomaticDashSubstitutionEnabled = false
        textView.isAutomaticTextReplacementEnabled = false
        textView.isAutomaticSpellingCorrectionEnabled = false
        // Log lines are often wider than the view; soft-wrap to width so
        // there's no horizontal scrollbar but long messages still readable.
        if let container = textView.textContainer {
            container.wis.accEnableThinking,
                            sampling_profile: this.accSamplingProfile,
                            external: externalRequest,
                        }),
                    });
                    if (!resp.ok) {
                        const err = await resp.json();
                        throw new Error(err.detail || 'Failed to add to queue');
                    }
                    const data = await resp.json();
                    this.accQueue = data.queue || [];
                    this.accRunning = data.running || false;
                    this.accCurrentModel = data.current_model || '';
                    if (data.last_progress) this.accProgress = data.last_progress;

                    // Connect SSE to current run
                    if (data.current_bench_id) {
                        this.accCurrentBenchId = data.current_bench_id;
                        this.connectAccSSE(data.current_bench_id);
                    }
                } catch (err) {
                    this.accError = err.message;
                }
            },

            async removeFromAccQueue(idx) {
                try {
                    await fetch(`/admin/api/bench/accuracy/queue/${idx}`, { method: 'DELETE' });
                    await this.loadAccQueueStatus();
                } catch (err) {
                    console.error('Failed to remove from queue:', err);
                }
            },

            connectAccSSE(benchId) {
                if (this.accEventSource) {
                    this.accEventSource.close();
                }
                this._stopAccPolling();

                const es = new EventSource(`/admin/api/bench/accuracy/${benchId}/stream`);
                this.accEventSource = es;

                es.onmessage = (event) => {
                    try {
                        const data = JSON.parse(event.data);
                        switch (data.type) {
                            case 'progress':
                                this.accProgress = data;
                                this.accCurrentModel = data.model_id || this.accCurrentModel;
                                break;
                            case 'result':
                                // Dedupe on replay: accuracy results are unique by
                                // (model_id, benchmark).
                                {
                                    const exists = this.accAllResults.some(
                                        r => r.model_id === data.data.model_id
                                          && r.benchmark === data.data.benchmark
                                    );
                                    if (!exists) {
                                        data.data._showCategories = false;
                                        this.accAllResults.push(data.data);
                                    }
                                }
                                break;
                            case 'done':
                                this.accProgress = null;
                                es.close();
                                this.accEventSource = null;
                                // Check for next in queue
                                this._pollForNextRun();
                                break;
                            case 'error':
                                this.accError = data.message;
                                this.accProgress = null;
                                es.close();
                                this.accEventSource = null;
                                this.loadAccQueueStatus();
                                break;
                        }
                    } catch (err) {
                        console.error('SSE parse error:', err);
                    }
                };

                es.onerror = () => {
                    es.close();
                    this.accEventSource = null;
                    // SSE disconnected — fall back to polling
                    this._startAccPolling();
  ay& scales,
    StreamOrDevice s = {});

// ---------------------------------------------------------------------------
// t5 MMA GEMM (Identity I-M): fused dequant + simdgroup matmul for prefill
// ---------------------------------------------------------------------------
// x      : [M, K]                   float16 or bfloat16
// w      : [N, n_groups * bpg]      uint8 t5 bytes
// scales : [N, n_groups]            float16 or bfloat16
// Returns [M, N].
array bonsai_t5_qmm(
    const array& x,
    const array& w,
    const array& scales,
    StreamOrDevice s = {});

std::pair<array, array> bonsai_spec_decode_verify(
    const array& draft,
    const array& target,
    StreamOrDevice s = {});

// ---------------------------------------------------------------------------
// NAX probe (mirrors mlx metal::is_nax_available)
// ---------------------------------------------------------------------------
bool is_nax_available();

} // namespace omlx::bonsai_kernels


# ===== FILE: omlx/custom_kernels/bonsai/csrc/quantized.h =====

// Copyright © 2023-2024 Apple Inc.

#include <metal_simdgroup>
#include <metal_simdgroup_matrix>
#include <metal_stdlib>

constant bool align_M [[function_constant(200)]];
constant bool align_N [[function_constant(201)]];
constant bool align_K [[function_constant(202)]];

using namespace metal;

#define MLX_MTL_CONST static constant constexpr const

MLX_MTL_CONST int SIMD_SIZE = 32;
MLX_MTL_CONST int QUAD_SIZE = 4;

template <int bits, int wsize = 8>
inline constexpr short get_pack_factor() {
  return (bits == 3 || bits == 5) ? 8 : (bits == 6 ? 4 : wsize / bits);
}

template <int bits, int wsize = 8>
inline constexpr short get_bytes_per_pack() {
  constexpr int power_of_2_bits = (bits & (bits - 1)) == 0;
  return power_of_2_bits ? (wsize / 8) : (bits == 5 ? 5 : 3);
}

template <typename T, typename U, int values_per_thread, int bits>
inline U load_vector(const device T* x, thread U* x_thread) {
  static_assert(
      bits == 1 || bits == 2 || bits == 3 || bits == 4 || bits == 5 ||
          bits == 6 || bits == 8,
      "Template undefined for bits not in {1, 2, 3, 4, 5, 6, 8}");

  U sum = 0;

  if (bits == 1) {
    // Pre-scale x by 1/2^k so qdot can use FMA (x_thread[k] * (wb & 2^k) = x[k] * bit_k).
    for (int i = 0; i < values_per_thread; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];
      x_thread[i]     = x[i];
      x_thread[i + 1] = x[i + 1] * U(0.5f);
      x_thread[i + 2] = x[i + 2] * U(0.25f);
      x_thread[i + 3] = x[i + 3] * U(0.125f);
      x_thread[i + 4] = x[i + 4] * U(0.0625f);
      x_thread[i + 5] = x[i + 5] * U(0.03125f);
      x_thread[i + 6] = x[i + 6] * U(0.015625f);
      x_thread[i + 7] = x[i + 7] * U(0.0078125f);
    }
  }

  else if (bits == 2) {
    for (int i = 0; i < values_per_thread; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i]     = x[i];
      x_thread[i + 1] = x[i + 1] * U(0.25f);
      x_thread[i + 2] = x[i + 2] * U(0.0625f);
      x_thread[i + 3] = x[i + 3] * U(0.015625f);
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < values_per_thread; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 8.0f;
      x_thread[i + 2] = x[i + 2] / 64.0f;
      x_thread[i + 3] = x[i + 3] / 2.0f;
      x_thread[i + 4] = x[i + 4] / 16.0f;
      x_thread[i + 5] = x[i + 5] / 128.0f;
      x_thread[i + 6] = x[i + 6] / 4.0f;
      x_thread[i + 7] = x[i + 7] / 32.0f;
    }
  }

  else if (bits == 4) {
    for (int i = 0; i < values_per_thread; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 16.0f;
      x_thread[i + 2] = x[i + 2] / 256.0f;
      x_thread[i + 3] = x[i + 3] / 4096.0f;
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < values_per_thread; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];
                 extended = True
                verified = ext_target
                verified_prompt_tokens = int(
                    getattr(output, "prompt_tokens", 0) or ext_target
                )
                verify_prefill_tps = float(getattr(output, "prompt_tps", 0.0) or 0.0)
                if verify_prefill_tps <= 0 and probe_seconds > 0:
                    verify_prefill_tps = verified_prompt_tokens / probe_seconds
                logger.info(
                    "Context bench: extension probe completed at %d tokens",
                    ext_target,
                )
            finally:
                relay.cancel()

        # Phase 5: apply — re-measure with the post-verify tracker state
        # (the near-ceiling prefill can raise the floor-chunk transient
        # charge) and write the tighter of the two, floored to 2k.
        await _progress(run, "apply", 0.2, "Re-checking admission boundary...")
        await _cleanup_between_probes(engine, scheduler)
        post_boundary = bisect_admission(fits, 1024, verified)
        final = verified
        if post_boundary > 0:
            # The re-bisect can be contaminated by the verify prefill's own
            # residue (buffer pool, last-chunk transient sample) — never
            # tighten below 90% of what physically completed. After a
            # FAILED extension probe the contamination is fresh and the
            # verified size completed moments ago, so it stands as-is.
            if extension_aborted:
                evidence_floor = floor_to_apply_granularity(verified)
            else:
                evidence_floor = floor_to_apply_granularity(
                    int(verified * _ABORT_EVIDENCE_SAFETY)
                )
            final = min(
                final,
                max(floor_to_apply_granularity(post_boundary), evidence_floor),
            )
        final = floor_to_apply_granularity(final)
        if final < _MIN_USEFUL_TOKENS:
            final = _MIN_USEFUL_TOKENS

        capped_by = "memory"
        if final >= floor_to_apply_granularity(cap):
            capped_by = cap_source

        applied = False
        sm = getattr(engine_pool, "_settings_manager", None)
        if sm is not None:
            try:
                settings = sm.get_settings(request.model_id)
                settings.max_context_window = final
                sm.set_settings(request.model_id, settings)
                applied = True
                logger.info(
                    "Context bench: applied max_context_window=%d for %s",
                    final,
                    request.model_id,
                )
            except Exception as exc:
                logger.warning(
                    "Context bench: failed to apply setting for %s: %s",
                    request.model_id,
                    exc,
                )
        await _progress(run, "apply", 0.8, "Applying context window setting...")

        result = {
            "model_id": request.model_id,
            "target_tokens": request.target_tokens,
            "native_context_length": native or None,
            "measured_tokens": boundary,
            "verified_tokens": verified,
            "verified_prompt_tokens": verified_prompt_tokens,
            "applied_tokens": final,
            "applied": applied,
            "capped_by": capped_by,
            "attempts": attempts,
            # True when the 1.2x extension probe completed and raised the
            # verified value beyond the analytic boundary.
            "extended": extended,
            # Prefill tok/s of the successful verify run — what a prompt at
            # the applied size actually prefills at in the current mode.
            "prefill_tps": round(verify_prefill_tps, 1),
            "duration_s": round(time.perf_counter() - overall_start, 1),
            # Mode the measurement ran under — the applied value only holds
            # while serving keeps the same prefill priority.
            "prefill_priority": (
                "speed"
                if getattr(scheduler, "_prefill_speed_priodthTracksTextView = true
            container.lineFragmentPadding = 0
        }
        textView.string = text
        return scroll
    }

    func updateNSView(_ scroll: NSScrollView, context: Context) {
        guard let textView = scroll.documentView as? NSTextView else { return }

        textView.backgroundColor = bgColor
        textView.textColor = fgColor
        if textView.string == text { return }

        // Decide whether to follow the tail before mutating the string.
        let wasPinnedToBottom: Bool = {
            let clip = scroll.contentView
            let visibleMaxY = clip.documentVisibleRect.maxY
            let documentMaxY = clip.documentRect.maxY
            // 40 pt slack — keeps "follow the tail" feel even if the user
            // nudged the scrollwheel a hair.
            return documentMaxY - visibleMaxY < 40
        }()

        textView.string = text

        if wasPinnedToBottom {
            DispatchQueue.main.async {
                textView.scrollToEndOfDocument(nil)
            }
        }
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/ModelCardSheet.swift =====

// PR — Downloads model card.
//
// Sheet that renders the upstream README for a model in the Downloads
// screen. Wired to two API surfaces:
//   • HF       → OMLXClient.getHFModelCard(repoId:)
//   • MS       → OMLXClient.getMSModelCard(modelId:)
//
// Both surface the same shape (model card + metadata; YAML front-matter
// stripped server-side, empty `model_card` when the upstream has no
// README), so a single sheet handles both — the `target`'s source enum
// just picks which client method to call and which upstream URL the
// "View on …" link points at.
//
// Rendering uses `MarkdownUI` (swift-markdown-ui) for full block support
// (headings, code blocks, tables, lists, images). Native
// `AttributedString(markdown:)` only handles inline formatting which
// would flatten the typical mlx-community README to plain text.

import SwiftUI
import AppKit
import MarkdownUI

// MARK: - Target / source

/// What the sheet is showing. Identifiable so `.sheet(item:)` can
/// drive presentation off the VM's `modelCardTarget` binding.
struct ModelCardTarget: Identifiable, Equatable, Sendable {
    let repoId: String
    let source: ModelCardSource

    /// `.sheet(item:)` uses this to decide when to re-present. Composing
    /// source into the id means switching HF↔MS for the same string
    /// re-fires the sheet's `.task(id:)` and refetches.
    var id: String { "\(source.rawValue):\(repoId)" }
}

enum ModelCardSource: String, Sendable, Equatable {
    case huggingFace = "hf"
    case modelScope  = "ms"

    var displayName: String {
        switch self {
        case .huggingFace: return "Hugging Face"
        case .modelScope:  return "ModelScope"
        }
    }

    /// Canonical upstream URL for the repo — used by the "View on …"
    /// footer link. Always points at the canonical origin even when the
    /// user has a mirror configured for downloads; the mirror is for
    /// transport, not browsing.
    func upstreamURL(repoId: String) -> URL? {
        switch self {
        case .huggingFace: return URL(string: "https://huggingface.co/\(repoId)")
        case .modelScope:  return URL(string: "https://modelscope.cn/models/\(repoId)")
        }
    }
}

/// Tabs available inside the sheet. The Files tab is HF-only — matches
/// the HTML admin which hides it for MS (MS file lists are usually
/// opaque sharded blobs that don't help the user decide).
enum ModelCardTab: Hashable, CaseIterable {
    case card, files, tags

    var label: String {
        switch self {
        case .card:
            return String(localized: "downloads.card.tab.card",
                          defaultValue: "Model Card",
                          comment: "Tab label in the model card sheet for the README content")
        case .files:
            return String(localized: "downloads.card.tab.files",
                          defaultValue: "Files",
                          comment: "Tab label in the model card sheet for the re              };
            },

            _startAccPolling() {
                this._stopAccPolling();
                this._accPollTimer = setInterval(async () => {
                    await this.loadAccQueueStatus();
                    // Load latest results too
                    try {
                        const resp = await fetch('/admin/api/bench/accuracy/results');
                        if (resp.ok) {
                            const data = await resp.json();
                            this.accAllResults = (data.results || []).map(r => ({ ...r, _showCategories: false }));
                        }
                    } catch (e) {}
                    // Try to reconnect SSE if running
                    if (this.accRunning && this.accCurrentBenchId && !this.accEventSource) {
                        this._stopAccPolling();
                        this.connectAccSSE(this.accCurrentBenchId);
                    }
                    if (!this.accRunning) {
                        this._stopAccPolling();
                    }
                }, 3000);
            },

            _stopAccPolling() {
                if (this._accPollTimer) {
                    clearInterval(this._accPollTimer);
                    this._accPollTimer = null;
                }
            },

            _pollForNextRun() {
                // After a run completes, poll briefly for the next run to start
                let attempts = 0;
                const poll = setInterval(async () => {
                    attempts++;
                    await this.loadAccQueueStatus();
                    if (this.accCurrentBenchId && this.accRunning) {
                        clearInterval(poll);
                        this.connectAccSSE(this.accCurrentBenchId);
                    } else if (!this.accRunning || attempts > 10) {
                        clearInterval(poll);
                    }
                }, 1000);
            },

            async cancelAccuracyBenchmark() {
                try {
                    await fetch('/admin/api/bench/accuracy/cancel', { method: 'POST' });
                } catch (err) {
                    console.error('Cancel error:', err);
                }
                this.accRunning = false;
                this.accProgress = null;
                this.accQueue = [];
                this.accCurrentModel = '';
                if (this.accEventSource) {
                    this.accEventSource.close();
                    this.accEventSource = null;
                }
            },

            async resetAccResults() {
                try {
                    await fetch('/admin/api/bench/accuracy/results/reset', { method: 'POST' });
                    this.accAllResults = [];
                } catch (err) {
                    console.error('Reset error:', err);
                }
            },

            accBuildText() {
                if (this.accAllResults.length === 0) return '';
                const pad = (s, w) => s.toString().padStart(w);
                const rpad = (s, w) => s.toString().padEnd(w);

                // Group by model
                const models = [...new Set(this.accAllResults.map(r => r.model_id))];
                const benchmarks = [...new Set(this.accAllResults.map(r => r.benchmark))];

                // Build lookup: model -> benchmark -> accuracy
                const lookup = {};
                for (const r of this.accAllResults) {
                    if (!lookup[r.model_id]) lookup[r.model_id] = {};
                    lookup[r.model_id][r.benchmark] = r;
                }

                // Full sizes lookup
                const fullSizes = {};
                for (const grp of this.accBenchmarkGroups) {
                    for (const bl of grp.benchmarks) fullSizes[bl.key] = bl.fullSize;
                }

                // Determine column widths
                const modelWidth = Math.max(12, ...models.map(m => m.length + 2));
                const modeW = 8;
                const sampledW = 14;
                const benchWidth = Math.max(14, .     x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 32.0f;
      x_thread[i + 2] = x[i + 2] / 4.0f;
      x_thread[i + 3] = x[i + 3] / 128.0f;
      x_thread[i + 4] = x[i + 4] / 16.0f;
      x_thread[i + 5] = x[i + 5] / 2.0f;
      x_thread[i + 6] = x[i + 6] / 64.0f;
      x_thread[i + 7] = x[i + 7] / 8.0f;
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < values_per_thread; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 64.0f;
      x_thread[i + 2] = x[i + 2] / 16.0f;
      x_thread[i + 3] = x[i + 3] / 4.0f;
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < values_per_thread; i++) {
      sum += x[i];
      x_thread[i] = x[i];
    }
  }

  return sum;
}

template <typename T, typename U, int values_per_thread, int bits>
inline U load_vector_safe(const device T* x, thread U* x_thread, int N) {
  static_assert(
      bits == 1 || bits == 2 || bits == 3 || bits == 4 || bits == 5 ||
          bits == 6 || bits == 8,
      "Template undefined for bits not in {1, 2, 3, 4, 5, 6, 8}");

  U sum = 0;

  if (bits == 1) {
    for (int i = 0; i < N; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];
      x_thread[i]     = x[i];
      x_thread[i + 1] = x[i + 1] * U(0.5f);
      x_thread[i + 2] = x[i + 2] * U(0.25f);
      x_thread[i + 3] = x[i + 3] * U(0.125f);
      x_thread[i + 4] = x[i + 4] * U(0.0625f);
      x_thread[i + 5] = x[i + 5] * U(0.03125f);
      x_thread[i + 6] = x[i + 6] * U(0.015625f);
      x_thread[i + 7] = x[i + 7] * U(0.0078125f);
    }
  }

  else if (bits == 2) {
    for (int i = 0; i < N; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i]     = x[i];
      x_thread[i + 1] = x[i + 1] * U(0.25f);
      x_thread[i + 2] = x[i + 2] * U(0.0625f);
      x_thread[i + 3] = x[i + 3] * U(0.015625f);
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < N; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];

      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 8.0f;
      x_thread[i + 2] = x[i + 2] / 64.0f;
      x_thread[i + 3] = x[i + 3] / 2.0f;
      x_thread[i + 4] = x[i + 4] / 16.0f;
      x_thread[i + 5] = x[i + 5] / 128.0f;
      x_thread[i + 6] = x[i + 6] / 4.0f;
      x_thread[i + 7] = x[i + 7] / 32.0f;
    }
  }

  else if (bits == 4) {
    for (int i = 0; i < N; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 16.0f;
      x_thread[i + 2] = x[i + 2] / 256.0f;
      x_thread[i + 3] = x[i + 3] / 4096.0f;
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < N; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 32.0f;
      x_thread[i + 2] = x[i + 2] / 4.0f;
      x_thread[i + 3] = x[i + 3] / 128.0f;
      x_thread[i + 4] = x[i + 4] / 16.0f;
      x_thread[i + 5] = x[i + 5] / 2.0f;
      x_thread[i + 6] = x[i + 6] / 64.0f;
      x_thread[i + 7] = x[i + 7] / 8.0f;
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < N; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 64.0f;
      x_thread[i + 2] = x[i + 2] / 16.0f;
      x_thread[i + 3] = x[i + 3] / 4.0f;
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < N; i++) {
      sum += x[i];
      x_thread[i] = x[i];
    }
  }

  for (int i = N; i < values_per_thread; i++) {
    x_thread[i] = 0;
  }

  return sum;
}

template <typename U, int values_per_thread, int bits>
inline U qdot(
    const device uint8_t* w,
    const thread U* x_thread,
    U scale,
    U bias,
    U sum) {
  static_assert(
      bits == 1 || bits == 2 || bits == 3 || bits == 4 || bits == 5 ||
          bits == 6 || bits == 8,
      "Template undefined for bits not in {1, 2, 3, 4, 5, 6, 8}");

  U accum = 0;

  if (bits == 1) {
    // One uinrity", False)
                else "context"
            ),
        }
        run.result = result
        await _send_event(run, {"type": "result", "data": result})

        # Phase 6: cleanup — unload the bench model (throughput parity).
        try:
            await engine_pool._unload_engine(request.model_id)
            logger.info("Context bench: unloaded %s after run", request.model_id)
        except Exception as exc:
            logger.warning(
                "Context bench: failed to unload %s: %s", request.model_id, exc
            )

        run.status = "completed"
        await _send_event(
            run,
            {
                "type": "done",
                "summary": {
                    "model_id": request.model_id,
                    "applied_tokens": final,
                    "total_time": result["duration_s"],
                },
            },
        )

    except asyncio.CancelledError:
        run.status = "cancelled"
        run.error_message = "Context benchmark cancelled by user"
        await _send_event(run, {"type": "error", "message": run.error_message})
        with contextlib.suppress(Exception):
            await engine_pool._unload_engine(request.model_id)

    except Exception as exc:
        logger.error("Context bench error: %s", exc, exc_info=True)
        run.status = "error"
        run.error_message = str(exc)
        await _send_event(run, {"type": "error", "message": str(exc)})
        with contextlib.suppress(Exception):
            await engine_pool._unload_engine(request.model_id)


# ===== FILE: omlx/admin/external_api.py =====

# SPDX-License-Identifier: Apache-2.0
"""OpenAI-compatible external endpoint client for admin benchmarks.

Shared by the throughput and accuracy benchmarks to run against a remote
/chat/completions endpoint instead of a local engine. Token counts always
come from the endpoint's usage payload — SSE chunks are never counted as
tokens because providers batch multiple tokens per chunk.
"""

import json
import logging
import re
import time
from dataclasses import dataclass
from typing import Any, Optional

import httpx
from pydantic import BaseModel, Field, SecretStr, field_validator

logger = logging.getLogger(__name__)

# read=3600 covers both the largest between-chunk gap on streams (TTFT of a
# very long prefill on a slow remote) and the full-response wait for
# non-streaming accuracy calls. Benchmarks are supervised and cancellable,
# so a generous ceiling beats spurious failures; connect=15 still fails
# dead endpoints fast.
DEFAULT_TIMEOUT = httpx.Timeout(connect=15.0, read=3600.0, write=120.0, pool=30.0)

_ERROR_DETAIL_MAX_CHARS = 300

_REASONING_FIELD_NAMES = ("reasoning_content", "reasoning", "analysis")

# Thinking models spend reasoning tokens before message.content, and those
# tokens count toward max_tokens on OpenAI-compatible APIs, so a small cap
# truncates them before they can answer (#2309). max_tokens only bounds
# runaway generation; non-thinking endpoints still stop after a few tokens.
_PREFLIGHT_MAX_TOKENS = 4096

# Provider-specific request JSON must not override fields owned by the
# benchmark or authentication layer.
PROTECTED_EXTRA_BODY_FIELDS = frozenset({
    "model",
    "messages",
    "stream",
    "stream_options",
    "max_tokens",
    "temperature",
    "api_key",
    "authorization",
})


class ExternalEndpointConfig(BaseModel):
    """Connection settings for an external OpenAI-compatible endpoint.

    api_key is a SecretStr so the key never leaks through repr() or logs.
    """

    base_url: str
    api_key: SecretStr = SecretStr("")
    model: str
    extra_body: dict[str, Any] = Field(default_factory=dict)

    @field_validator("base_url")
    @classmethod
    def validate_base_url(cls, v: str) -> str:
        v = v.strip().rstrip("/")
        if not v.startswith(("http://", "https://")):
            raise ValueError("base_url must start with http:// or https://")
        return v

    @field_validator("model")
    @classmethod
    def validate_model(cls, v: str) -> str:
        v = v.strip()
        po file list")
        case .tags:
            return String(localized: "downloads.card.tab.tags",
                          defaultValue: "Tags",
                          comment: "Tab label in the model card sheet for the repo tag list")
        }
    }

    static func available(for source: ModelCardSource) -> [ModelCardTab] {
        switch source {
        case .huggingFace: return [.card, .files, .tags]
        case .modelScope:  return [.card, .tags]
        }
    }
}

// MARK: - Sheet

@MainActor
struct ModelCardSheet: View {
    let target: ModelCardTarget
    let client: OMLXClient
    /// Triggered by the in-sheet Download button. The host wires this
    /// to `vm.startDownload(repo:)` so the action plays nicely with
    /// the existing source-routed downloader plumbing. Sheet dismisses
    /// itself on tap so the user lands back on the row with the task
    /// already moving in the Active section.
    let onDownload: (String) -> Void

    @State private var state: LoadState = .idle
    /// Currently selected tab in the sheet. Reset to `.card` whenever
    /// the target changes (different repo opened) so we never inherit
    /// a stale Files/Tags selection from a previous model.
    @State private var activeTab: ModelCardTab = .card
    @Environment(\.dismiss) private var dismiss
    @Environment(\.omlxTheme) private var theme

    enum LoadState: Equatable {
        case idle
        case loading
        case loaded(ModelCardDTO)
        case failed(String)
    }

    var body: some View {
        VStack(spacing: 0) {
            header
            stateRegion
        }
        .frame(width: 720, height: 600)
        .background(theme.windowBg)
        .task(id: target.id) {
            // Reset tab selection on every (re)open so a tab the
            // previous repo had (e.g. Files on HF) doesn't stick when
            // the user opens an MS card next.
            activeTab = .card
            await load()
        }
    }

    // MARK: Header

    private var header: some View {
        HStack(alignment: .center, spacing: 12) {
            VStack(alignment: .leading, spacing: 4) {
                Text(target.repoId)
                    .font(.omlxText(15, weight: .semibold))
                    .foregroundStyle(theme.text)
                    .textSelection(.enabled)
                    .lineLimit(1)
                    .truncationMode(.middle)
                Text(target.source.displayName)
                    .font(.omlxText(11, weight: .medium))
                    .foregroundStyle(theme.textSecondary)
                    .textCase(.uppercase)
                    .kerning(0.6)
            }
            Spacer(minLength: 12)
            Button {
                dismiss()
            } label: {
                Image(systemName: "xmark")
                    .font(.system(size: 11, weight: .bold))
                    .foregroundStyle(theme.textSecondary)
                    .padding(6)
                    .background(theme.controlBg)
                    .clipShape(Circle())
            }
            .buttonStyle(.plain)
            .keyboardShortcut(.cancelAction)
            .help(String(localized: "downloads.card.close",
                         defaultValue: "Close",
                         comment: "Tooltip on the model card sheet's close button"))
        }
        .padding(.horizontal, 20)
        .padding(.vertical, 14)
    }

    // MARK: State-dependent region

    @ViewBuilder
    private var stateRegion: some View {
        switch state {
        case .idle, .loading:
            Divider().overlay(theme.groupBorder)
            loadingView
        case .failed(let message):
            Divider().overlay(theme.groupBorder)
            errorView(message: message)
        case .loaded(let dto):
            metadataRow(dto: dto)
            if dto.isAdapter == true {
                loraBanner
            }
            tabBar
            Divider().overlay(theme.groupBorder)
            tabBody(dto: dto)
            footer(dto: dto)
        }
    }

    // MARK: Tab bar

    private var tabBar..benchmarks.map(b => b.length + 2));

                let lines = [];
                lines.push('Intelligence Benchmark Comparison');
                lines.push('');

                // Header row
                let header = rpad('', benchWidth) + rpad('Mode', modeW) + rpad('Sampled', sampledW);
                for (const m of models) header += pad(m, modelWidth);
                lines.push(header);
                lines.push('-'.repeat(benchWidth + modeW + sampledW + models.length * modelWidth));

                // Data rows
                for (const b of benchmarks) {
                    // Get sample info from first available result for this benchmark
                    const sample = models.map(m => lookup[m]?.[b]).find(r => r);
                    const total = sample?.total || 0;
                    const full = fullSizes[b] || 0;
                    const isFull = total >= full;
                    const mode = isFull ? 'Full' : 'Sample';
                    const sampledStr = isFull ? String(full) : (total + '/' + full);

                    let row = rpad(b.toUpperCase(), benchWidth) + rpad(mode, modeW) + rpad(sampledStr, sampledW);
                    for (const m of models) {
                        const r = lookup[m]?.[b];
                        row += pad(r ? (r.accuracy * 100).toFixed(1) + '%' : '-', modelWidth);
                    }
                    lines.push(row);
                }

                // Detail section per model
                lines.push('');
                lines.push('--- Detail ---');
                for (const m of models) {
                    lines.push('');
                    lines.push('Model: ' + m);
                    lines.push(rpad('Benchmark', 16) + pad('Accuracy', 10) + pad('Correct', 10) + pad('Total', 8) + pad('Time(s)', 10) + pad('Think', 8));
                    lines.push('-'.repeat(62));
                    for (const r of this.accAllResults.filter(r => r.model_id === m)) {
                        lines.push(
                            rpad(r.benchmark.toUpperCase(), 16) +
                            pad((r.accuracy * 100).toFixed(1) + '%', 10) +
                            pad(r.correct, 10) +
                            pad(r.total, 8) +
                            pad(r.time_s, 10) +
                            pad(r.thinking_used ? 'Yes' : 'No', 8)
                        );
                        if (r.external) {
                            lines.push(
                                `  Valid responses: ${r.valid_response_count}/${r.total}` +
                                ` (${(r.valid_response_rate * 100).toFixed(1)}%)` +
                                ` · Valid-answer accuracy: ${(r.valid_answer_accuracy * 100).toFixed(1)}%` +
                                ` · Empty: ${r.empty_content_count}` +
                                ` · Truncated: ${r.truncated_count}` +
                                ` · Timeout: ${r.timeout_count}` +
                                ` · HTTP: ${r.http_error_count}` +
                                ` · Connection: ${r.connection_error_count}` +
                                ` · Invalid: ${r.invalid_response_count}` +
                                ` · Parse: ${r.parse_error_count}`
                            );
                        }
                    }
                }

                return lines.join('\n');
            },

            accCopyText() {
                const text = this.accBuildText();
                const onSuccess = () => {
                    this.accCopied = true;
                    setTimeout(() => { this.accCopied = false; }, 2000);
                };
                if (navigator.clipboard && navigator.clipboard.writeText) {
                    navigator.clipboard.writeText(text).then(onSuccess).catch(() => {
                        const ta = document.getElementById('accTextarea');
                        if (ta) { ta.select(); document.execCommand('copy'); onSuccess(); }
                    });
                } else {
                    const ta = document.getElementById('t32 load per 32 elements; x_thread is pre-scaled by 1/2^k so
    // x_thread[k] * (wb & 2^k) = x[k] * bit_k — pure FMA, no select/bool.
    const device uint32_t* wp = (const device uint32_t*)w;
    for (int i = 0; i < (values_per_thread / 32); i++) {
      uint32_t wb32 = wp[i];
      for (int j = 0; j < 4; j++) {
        uint8_t wb = uint8_t(wb32 >> (8 * j));
        int base = 32 * i + 8 * j;
        accum += x_thread[base + 0] * U(wb & 0x01);
        accum += x_thread[base + 1] * U(wb & 0x02);
        accum += x_thread[base + 2] * U(wb & 0x04);
        accum += x_thread[base + 3] * U(wb & 0x08);
        accum += x_thread[base + 4] * U(wb & 0x10);
        accum += x_thread[base + 5] * U(wb & 0x20);
        accum += x_thread[base + 6] * U(wb & 0x40);
        accum += x_thread[base + 7] * U(wb & 0x80);
      }
    }
  }

  else if (bits == 2) {
    // One uint32 load covers 16 packed 2-bit values (4× fewer loads than byte-by-byte).
    // x_thread is pre-scaled by 1/4^k so x_thread[k] * (wb & shifted_mask_k) = x[k]*q_k.
    const device uint32_t* wp = (const device uint32_t*)w;
    for (int i = 0; i < (values_per_thread / 16); i++) {
      uint32_t wb32 = wp[i];
      for (int j = 0; j < 4; j++) {
        uint8_t wb = uint8_t(wb32 >> (8 * j));
        int base = 16 * i + 4 * j;
        accum += x_thread[base + 0] * U(wb & 0x03)
              +  x_thread[base + 1] * U(wb & 0x0c)
              +  x_thread[base + 2] * U(wb & 0x30)
              +  x_thread[base + 3] * U(wb & 0xc0);
      }
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      x_thread += 8 * i;
      w += 3 * i;

      accum += (w[0] & 0x07) * x_thread[0];
      accum += (w[0] & 0x38) * x_thread[1];
      accum += (w[0] & 0xc0) * x_thread[2];
      accum += (w[1] & 0x01) * (x_thread[2] * 256.0f);

      accum += (w[1] & 0x0e) * x_thread[3];
      accum += (w[1] & 0x70) * x_thread[4];
      accum += (w[1] & 0x80) * x_thread[5];
      accum += (w[2] & 0x03) * (x_thread[5] * 256.0f);

      accum += (w[2] & 0x1c) * x_thread[6];
      accum += (w[2] & 0xe0) * x_thread[7];
    }
  }

  else if (bits == 4) {
    const device uint16_t* ws = (const device uint16_t*)w;
    for (int i = 0; i < (values_per_thread / 4); i++) {
      accum +=
          (x_thread[4 * i] * (ws[i] & 0x000f) +
           x_thread[4 * i + 1] * (ws[i] & 0x00f0) +
           x_thread[4 * i + 2] * (ws[i] & 0x0f00) +
           x_thread[4 * i + 3] * (ws[i] & 0xf000));
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      x_thread += 8 * i;
      w += 5 * i;

      accum += (w[0] & 0x1f) * x_thread[0];
      accum += (w[0] & 0xe0) * x_thread[1];
      accum += (w[1] & 0x3) * (x_thread[1] * 256.0f);
      accum += (w[1] & 0x7c) * x_thread[2];
      accum += (w[1] & 0x80) * x_thread[3];
      accum += (w[2] & 0xf) * (x_thread[3] * 256.0f);
      accum += (w[2] & 0xf0) * x_thread[4];
      accum += (w[3] & 0x1) * (x_thread[4] * 256.0f);
      accum += (w[3] & 0x3e) * x_thread[5];
      accum += (w[3] & 0xc0) * x_thread[6];
      accum += (w[4] & 0x7) * (x_thread[6] * 256.0f);
      accum += (w[4] & 0xf8) * x_thread[7];
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < (values_per_thread / 4); i++) {
      x_thread += 4 * i;
      w += 3 * i;

      accum += (w[0] & 0x3f) * x_thread[0];

      accum += (w[0] & 0xc0) * x_thread[1];
      accum += (w[1] & 0x0f) * (x_thread[1] * 256.0f);

      accum += (w[1] & 0xf0) * x_thread[2];
      accum += (w[2] & 0x03) * (x_thread[2] * 256.0f);

      accum += (w[2] & 0xfc) * x_thread[3];
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < values_per_thread; i++) {
      accum += x_thread[i] * w[i];
    }
  }

  return scale * accum + sum * bias;
}

template <typename U, int values_per_thread, int bits>
inline U qdot_safe(
    const device uint8_t* w,
    const thread U* x_thread,
    U scale,
    U bias,
    U sum,
    int N) {
  static_assert(
      bits == 1 || bits == 2 || bits == 3 || bits == 4 || bits == 5 ||
          bits == 6 || bits == 8,
      "Templif not v:
            raise ValueError("model must not be empty")
        return v

    @field_validator("extra_body", mode="before")
    @classmethod
    def validate_extra_body(cls, v: Any) -> dict[str, Any]:
        if v is None:
            return {}
        if not isinstance(v, dict):
            raise ValueError("extra_body must be a JSON object")
        blocked = sorted(
            str(key)
            for key in v
            if str(key).lower() in PROTECTED_EXTRA_BODY_FIELDS
        )
        if blocked:
            raise ValueError(
                "extra_body cannot override protected field(s): "
                + ", ".join(blocked)
            )
        return dict(v)


class ExternalEndpointError(Exception):
    """User-presentable failure talking to an external endpoint."""

    def __init__(self, message: str, status: str = "invalid_response"):
        super().__init__(message)
        self.status = status


@dataclass
class StreamStats:
    """Timing and token stats from one streamed chat completion."""

    prompt_tokens: int
    completion_tokens: int
    cached_tokens: int
    start_time: float
    first_content_time: float
    last_content_time: float
    end_time: float
    text: str
    # False when the stream carried no content or reasoning delta at all.
    # first/last_content_time then fall back to end_time, so every timing
    # derived from them (TTFT, prefill rate, decode rate) describes the
    # whole response instead of the phase it claims to measure.
    content_observed: bool = True


@dataclass
class ChatResult:
    """Non-streaming chat completion result."""

    text: str
    prompt_tokens: int = 0
    completion_tokens: int = 0
    finish_reason: Optional[str] = None
    status: str = "ok"
    reasoning_fields_present: tuple[str, ...] = ()
    reasoning_fields_nonempty: tuple[str, ...] = ()


def _extract_error_detail(body: str) -> str:
    """Pull a short human-readable message out of an error response body."""
    try:
        data = json.loads(body)
        if isinstance(data, dict):
            err = data.get("error")
            if isinstance(err, dict) and err.get("message"):
                return str(err["message"])[:_ERROR_DETAIL_MAX_CHARS]
            for key in ("message", "detail"):
                if data.get(key):
                    return str(data[key])[:_ERROR_DETAIL_MAX_CHARS]
    except ValueError:
        pass
    text = body.strip()
    if "<" in text and ">" in text:
        return f"unexpected non-JSON response ({len(body)} bytes)"
    return text[:_ERROR_DETAIL_MAX_CHARS] or "no response body"


class ExternalAPIClient:
    """Async client for an external OpenAI-compatible /chat/completions API.

    Provider-specific fields may be supplied through config.extra_body. The
    config validator prevents them from overriding benchmark-owned or
    authentication-related fields.
    """

    def __init__(
        self,
        config: ExternalEndpointConfig,
        timeout: httpx.Timeout = DEFAULT_TIMEOUT,
        transport: Optional[httpx.AsyncBaseTransport] = None,
    ):
        self._config = config
        self._chat_url = f"{config.base_url}/chat/completions"
        headers = {}
        key = config.api_key.get_secret_value()
        if key:
            headers["Authorization"] = f"Bearer {key}"
        # transport is injectable for tests (httpx.MockTransport).
        self._client = httpx.AsyncClient(
            headers=headers,
            timeout=timeout,
            limits=httpx.Limits(max_connections=64),
            transport=transport,
        )

    async def aclose(self) -> None:
        await self._client.aclose()

    def _build_body(
        self,
        messages: list[dict],
        max_tokens: int,
        temperature: Optional[float],
        stream: bool,
    ) -> dict:
        body: dict[str, Any] = {
            "model": self._config.model,
            "messages": messages,
            "max_tokens": max_tokens,
        }
        if temperature is not None:
            body["temperature"] = temperature
        if stream:
            bod: some View {
        let available = ModelCardTab.available(for: target.source)
        return HStack(spacing: 6) {
            ForEach(available, id: \.self) { tab in
                tabButton(tab: tab, isSelected: activeTab == tab)
            }
            Spacer(minLength: 0)
        }
        .padding(.horizontal, 20)
        .padding(.bottom, 6)
    }

    private func tabButton(tab: ModelCardTab, isSelected: Bool) -> some View {
        Button {
            activeTab = tab
        } label: {
            Text(tab.label)
                .font(.omlxText(11.5, weight: .semibold))
                .foregroundStyle(isSelected ? theme.text : theme.textSecondary)
                .padding(.horizontal, 10)
                .padding(.vertical, 4)
                .background(
                    Capsule().fill(isSelected ? theme.controlBg : Color.clear)
                )
                .overlay(
                    Capsule().strokeBorder(isSelected ? theme.inputBorder : Color.clear,
                                           lineWidth: 0.5)
                )
        }
        .buttonStyle(.plain)
    }

    // MARK: Tab body switch

    @ViewBuilder
    private func tabBody(dto: ModelCardDTO) -> some View {
        switch activeTab {
        case .card:
            cardBody(markdown: dto.modelCard)
        case .files:
            filesBody(files: dto.files ?? [])
        case .tags:
            tagsBody(tags: dto.tags ?? [])
        }
    }

    // MARK: Metadata badges (gap #1)

    @ViewBuilder
    private func metadataRow(dto: ModelCardDTO) -> some View {
        // Skip rendering the row entirely when none of the fields are
        // populated — keeps the sheet from showing a hollow strip on
        // metadata-poor repos.
        let hasAnyMetadata = dto.paramsFormatted != nil
            || dto.sizeFormatted != nil
            || dto.pipelineTag != nil
            || (dto.downloads ?? 0) > 0
            || (dto.likes ?? 0) > 0
        if hasAnyMetadata {
            HStack(spacing: 8) {
                if let p = dto.paramsFormatted, !p.isEmpty {
                    metaChip(text: p, accent: false)
                }
                if let s = dto.sizeFormatted, !s.isEmpty {
                    metaChip(text: s, accent: false)
                }
                if let tag = dto.pipelineTag, !tag.isEmpty {
                    metaChip(text: tag, accent: true)
                }
                Spacer(minLength: 6)
                if let d = dto.downloads, d > 0 {
                    metaCounter(symbol: "arrow.down.circle", value: d)
                }
                if let l = dto.likes, l > 0 {
                    metaCounter(symbol: "heart", value: l)
                }
            }
            .padding(.horizontal, 20)
            .padding(.bottom, 12)
        }
    }

    private func metaChip(text: String, accent: Bool) -> some View {
        Text(text)
            .font(.omlxText(10.5, weight: .heavy))
            .kerning(0.4)
            .textCase(.uppercase)
            .foregroundStyle(accent ? theme.accent : theme.textSecondary)
            .padding(.horizontal, 8)
            .frame(height: 22)
            .background(
                Capsule().fill(accent ? theme.accent.opacity(0.12) : theme.codeBg)
            )
            .overlay(
                Capsule().strokeBorder(accent ? theme.accent.opacity(0.25) : theme.inputBorder,
                                       lineWidth: 0.5)
            )
    }

    private func metaCounter(symbol: String, value: Int) -> some View {
        HStack(spacing: 3) {
            Image(systemName: symbol)
                .font(.system(size: 10, weight: .medium))
            Text(Self.compactCount(value))
                .font(.omlxMono(11))
        }
        .foregroundStyle(theme.textSecondary)
    }

    // MARK: LoRA warning (gap #4)

    private var loraBanner: some View {
        HStack(alignment: .top, spacing: 8) {
            Image(systemName: "exclamationmark.triangle.fill")
                .font(.system(size: 12))
                .foregroundStyle(theme.warningText)accTextarea');
                    if (ta) { ta.select(); document.execCommand('copy'); onSuccess(); }
                }
            },

            accDownloadResult(r, format) {
                const filename = `${r.model_id}_${r.benchmark}.${format}`;
                let content, mime;
                const qr = r.question_results || [];

                if (format === 'json') {
                    const exportData = {
                        model_id: r.model_id,
                        benchmark: r.benchmark,
                        accuracy: r.accuracy,
                        correct: r.correct,
                        total: r.total,
                        time_s: r.time_s,
                        thinking_used: r.thinking_used || false,
                        category_scores: r.category_scores || null,
                        questions: qr,
                    };
                    if (r.external) {
                        Object.assign(exportData, {
                            valid_response_count: r.valid_response_count,
                            empty_content_count: r.empty_content_count,
                            truncated_count: r.truncated_count,
                            timeout_count: r.timeout_count,
                            http_error_count: r.http_error_count,
                            connection_error_count: r.connection_error_count,
                            invalid_response_count: r.invalid_response_count,
                            parse_error_count: r.parse_error_count,
                            wrong_count: r.wrong_count,
                            valid_response_rate: r.valid_response_rate,
                            valid_answer_accuracy: r.valid_answer_accuracy,
                            reliability_warning: r.reliability_warning,
                        });
                    }
                    content = JSON.stringify(exportData, null, 2);
                    mime = 'application/json';
                } else if (format === 'csv') {
                    const esc = s => '"' + (s || '').replace(/"/g, '""') + '"';
                    const lines = [r.external
                        ? 'id,category,status,correct,expected,predicted,finish_reason,reasoning_fields,prompt_tokens,completion_tokens,error_message,question,raw_response,time_s'
                        : 'id,category,correct,expected,predicted,question,raw_response,time_s'];
                    for (const q of qr) {
                        if (r.external) {
                            lines.push([
                                q.id, esc(q.category || ''), esc(q.status || ''), q.correct,
                                esc(q.expected), esc(q.predicted), esc(q.finish_reason || ''),
                                esc((q.reasoning_fields_nonempty || []).join('|')),
                                q.prompt_tokens || 0, q.completion_tokens || 0,
                                esc(q.error_message || ''), esc(q.question),
                                esc(q.raw_response), q.time_s,
                            ].join(','));
                        } else {
                            lines.push([q.id, esc(q.category || ''), q.correct, esc(q.expected), esc(q.predicted), esc(q.question), esc(q.raw_response), q.time_s].join(','));
                        }
                    }
                    content = lines.join('\n');
                    mime = 'text/csv';
                } else {
                    const lines = [
                        `Model: ${r.model_id}`,
                        `Benchmark: ${r.benchmark.toUpperCase()}`,
                        `Accuracy: ${(r.accuracy * 100).toFixed(1)}% (${r.correct}/${r.total})`,
                        `Time: ${r.time_s}s`,
                        '',
                    ];
                    if (r.external) {
                        lines.splice(4, 0,
                            `Valid responses: ${r.valid_response_count}/${r.total} (${(r.valid_response_rate * 100).toFixed(1)}%)`,
                            `Valid-answer accuracy: ${(r.valid_answer_accuracy * 10ate undefined for bits not in {1, 2, 3, 4, 5, 6, 8}");

  U accum = 0;

  if (bits == 1) {
    for (int i = 0; i < (N / 8); i++) {
      uint8_t wb = w[i];
      accum += x_thread[8 * i + 0] * U(wb & 0x01);
      accum += x_thread[8 * i + 1] * U(wb & 0x02);
      accum += x_thread[8 * i + 2] * U(wb & 0x04);
      accum += x_thread[8 * i + 3] * U(wb & 0x08);
      accum += x_thread[8 * i + 4] * U(wb & 0x10);
      accum += x_thread[8 * i + 5] * U(wb & 0x20);
      accum += x_thread[8 * i + 6] * U(wb & 0x40);
      accum += x_thread[8 * i + 7] * U(wb & 0x80);
    }
  }

  else if (bits == 2) {
    // uint32 loads for 16-aligned chunks; byte loads for any remainder.
    const device uint32_t* wp = (const device uint32_t*)w;
    int i = 0;
    for (; i < (N / 16); i++) {
      uint32_t wb32 = wp[i];
      for (int j = 0; j < 4; j++) {
        uint8_t wb = uint8_t(wb32 >> (8 * j));
        int base = 16 * i + 4 * j;
        accum += x_thread[base + 0] * U(wb & 0x03)
              +  x_thread[base + 1] * U(wb & 0x0c)
              +  x_thread[base + 2] * U(wb & 0x30)
              +  x_thread[base + 3] * U(wb & 0xc0);
      }
    }
    for (int k = i * 4; k < (N / 4); k++) {
      accum += x_thread[4 * k + 0] * U(w[k] & 0x03)
            +  x_thread[4 * k + 1] * U(w[k] & 0x0c)
            +  x_thread[4 * k + 2] * U(w[k] & 0x30)
            +  x_thread[4 * k + 3] * U(w[k] & 0xc0);
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < (N / 8); i++) {
      x_thread += 8 * i;
      w += 3 * i;

      accum += (w[0] & 0x07) * x_thread[0];
      accum += (w[0] & 0x38) * x_thread[1];
      accum += (w[0] & 0xc0) * x_thread[2];
      accum += (w[1] & 0x01) * (x_thread[2] * 256.0f);

      accum += (w[1] & 0x0e) * x_thread[3];
      accum += (w[1] & 0x70) * x_thread[4];
      accum += (w[1] & 0x80) * x_thread[5];
      accum += (w[2] & 0x03) * (x_thread[5] * 256.0f);

      accum += (w[2] & 0x1c) * x_thread[6];
      accum += (w[2] & 0xe0) * x_thread[7];
    }
  }

  else if (bits == 4) {
    const device uint16_t* ws = (const device uint16_t*)w;
    for (int i = 0; i < (N / 4); i++) {
      accum +=
          (x_thread[4 * i] * (ws[i] & 0x000f) +
           x_thread[4 * i + 1] * (ws[i] & 0x00f0) +
           x_thread[4 * i + 2] * (ws[i] & 0x0f00) +
           x_thread[4 * i + 3] * (ws[i] & 0xf000));
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < (N / 8); i++) {
      x_thread += 8 * i;
      w += 5 * i;

      accum += (w[0] & 0x1f) * x_thread[0];
      accum += (w[0] & 0xe0) * x_thread[1];
      accum += (w[1] & 0x3) * (x_thread[1] * 256.0f);
      accum += (w[1] & 0x7c) * x_thread[2];
      accum += (w[1] & 0x80) * x_thread[3];
      accum += (w[2] & 0xf) * (x_thread[3] * 256.0f);
      accum += (w[2] & 0xf0) * x_thread[4];
      accum += (w[3] & 0x1) * (x_thread[4] * 256.0f);
      accum += (w[3] & 0x3e) * x_thread[5];
      accum += (w[3] & 0xc0) * x_thread[6];
      accum += (w[4] & 0x7) * (x_thread[6] * 256.0f);
      accum += (w[4] & 0xf8) * x_thread[7];
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < (N / 4); i++) {
      x_thread += 4 * i;
      w += 3 * i;

      accum += (w[0] & 0x3f) * x_thread[0];

      accum += (w[0] & 0xc0) * x_thread[1];
      accum += (w[1] & 0x0f) * (x_thread[1] * 256.0f);

      accum += (w[1] & 0xf0) * x_thread[2];
      accum += (w[2] & 0x03) * (x_thread[2] * 256.0f);

      accum += (w[2] & 0xfc) * x_thread[3];
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < N; i++) {
      accum += x_thread[i] * w[i];
    }
  }

  return scale * accum + sum * bias;
}

template <typename U, int values_per_thread, int bits>
inline void
qouter(const thread uint8_t* w, U x, U scale, U bias, thread U* result) {
  static_assert(
      bits == 1 || bits == 2 || bits == 3 || bits == 4 || bits == 5 ||
          bits == 6 || bits == 8,
      "Template undefined for bits not in {1, 2, 3, 4, 5, 6, 8}");

  if (bits == 1) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      uint8_t wb = w[i];
      result[8 * i] += x * (select(U(0), scale, bool(wb & 0x01)) + bias);
      rey["stream"] = True
            body["stream_options"] = {"include_usage": True}
        body.update(self._config.extra_body)
        return body

    def _redact_secret(self, text: str) -> str:
        """Defensively remove the configured key from provider errors."""
        key = self._config.api_key.get_secret_value()
        if key:
            return text.replace(key, "[REDACTED]")
        return text

    def _map_transport_error(self, exc: httpx.HTTPError) -> ExternalEndpointError:
        base_url = self._config.base_url
        if isinstance(exc, httpx.TimeoutException):
            if isinstance(exc, httpx.ConnectTimeout):
                return ExternalEndpointError(
                    f"Timed out connecting to external endpoint {base_url}",
                    status="timeout",
                )
            return ExternalEndpointError(
                "External endpoint timed out while waiting for a response",
                status="timeout",
            )
        if isinstance(exc, httpx.ConnectError):
            return ExternalEndpointError(
                self._redact_secret(
                    f"Cannot connect to external endpoint {base_url}: {exc}"
                ),
                status="connection_error",
            )
        return ExternalEndpointError(
            self._redact_secret(
                f"External endpoint request failed: {type(exc).__name__}: {exc}"
            ),
            status="connection_error",
        )

    def _status_error(self, status: int, body_text: str) -> ExternalEndpointError:
        if status in (401, 403):
            return ExternalEndpointError(
                f"External endpoint rejected the API key (HTTP {status})",
                status="http_error",
            )
        detail = self._redact_secret(_extract_error_detail(body_text))
        return ExternalEndpointError(
            f"External endpoint returned HTTP {status}: {detail}",
            status="http_error",
        )

    @staticmethod
    def _reasoning_diagnostics(
        message: dict[str, Any],
    ) -> tuple[tuple[str, ...], tuple[str, ...]]:
        present: list[str] = []
        nonempty: list[str] = []
        for name in _REASONING_FIELD_NAMES:
            if name not in message:
                continue
            present.append(name)
            value = message.get(name)
            if isinstance(value, str):
                has_value = bool(value.strip())
            else:
                has_value = value is not None and bool(value)
            if has_value:
                nonempty.append(name)
        return tuple(present), tuple(nonempty)

    @staticmethod
    def _usage_int(usage: dict[str, Any], name: str) -> int:
        try:
            return int(usage.get(name) or 0)
        except (TypeError, ValueError):
            return 0

    async def chat_completion(
        self,
        messages: list[dict],
        max_tokens: int,
        temperature: Optional[float],
    ) -> ChatResult:
        """Send a non-streaming chat completion request."""
        body = self._build_body(messages, max_tokens, temperature, stream=False)
        try:
            response = await self._client.post(self._chat_url, json=body)
        except httpx.HTTPError as e:
            raise self._map_transport_error(e) from e
        if response.status_code != 200:
            raise self._status_error(response.status_code, response.text)
        try:
            data = response.json()
        except ValueError as e:
            raise ExternalEndpointError(
                "External endpoint returned a non-JSON response",
                status="invalid_response",
            ) from e

        try:
            if not isinstance(data, dict):
                raise TypeError("top-level response is not an object")
            choices = data.get("choices")
            if not isinstance(choices, list) or not choices:
                raise KeyError("choices[0]")
            choice = choices[0]
            if not isinstance(choice, dict):
                raise TypeError("choices[0] is not an object")
            Text(String(localized: "downloads.card.lora_warning",
                        defaultValue: "This is a LoRA adapter. It needs a compatible base model to run — downloading on its own won't load in oMLX.",
                        comment: "Warning banner shown in the model card sheet when the repo is an adapter rather than a full model"))
                .font(.omlxText(11))
                .foregroundStyle(theme.text)
                .fixedSize(horizontal: false, vertical: true)
            Spacer(minLength: 0)
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 8)
        .background(theme.warningBg)
        .overlay(
            RoundedRectangle(cornerRadius: 6, style: .continuous)
                .strokeBorder(theme.warningText.opacity(0.25), lineWidth: 0.5)
        )
        .padding(.horizontal, 20)
        .padding(.bottom, 10)
    }

    // MARK: Card body

    @ViewBuilder
    private func cardBody(markdown raw: String) -> some View {
        let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
        if trimmed.isEmpty {
            VStack(spacing: 10) {
                Image(systemName: "doc.text.magnifyingglass")
                    .font(.system(size: 32, weight: .light))
                    .foregroundStyle(theme.textTertiary)
                Text(String(localized: "downloads.card.empty",
                            defaultValue: "This model doesn't ship a README.",
                            comment: "Empty state shown when the upstream repo has no model card"))
                    .font(.omlxText(13))
                    .foregroundStyle(theme.textSecondary)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .padding(24)
        } else {
            ScrollView {
                Markdown(trimmed)
                    .markdownTheme(.docC)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(20)
                    .textSelection(.enabled)
            }
        }
    }

    // MARK: Files tab (gap #5)

    @ViewBuilder
    private func filesBody(files: [ModelCardFile]) -> some View {
        if files.isEmpty {
            emptyStateView(
                symbol: "doc.text.below.ecg",
                message: String(localized: "downloads.card.files.empty",
                                defaultValue: "No files reported.",
                                comment: "Empty state in the Files tab when the upstream API doesn't list any files")
            )
        } else {
            ScrollView {
                VStack(alignment: .leading, spacing: 0) {
                    ForEach(Array(files.enumerated()), id: \.element.id) { idx, file in
                        HStack(alignment: .firstTextBaseline, spacing: 8) {
                            Text(file.name)
                                .font(.omlxMono(12))
                                .foregroundStyle(theme.text)
                                .textSelection(.enabled)
                                .lineLimit(1)
                                .truncationMode(.middle)
                            Spacer(minLength: 8)
                            if let s = file.sizeFormatted, !s.isEmpty {
                                Text(s)
                                    .font(.omlxMono(11))
                                    .foregroundStyle(theme.textSecondary)
                            }
                        }
                        .padding(.horizontal, 20)
                        .padding(.vertical, 8)
                        if idx < files.count - 1 {
                            Divider().opacity(0.4)
                        }
                    }
                }
                .padding(.vertical, 4)
            }
        }
    }

    // MARK: Tags tab (gap #6)

    @ViewBuilder
    private func tagsBody(tags: [String]) -> some View {
        if tags.isEmpty {
            emptyStateView(
                symbol: "tag",
                message: String(localized: "downloads.card.tags.empty",
                                de0).toFixed(1)}%`,
                            `Empty: ${r.empty_content_count}; Truncated: ${r.truncated_count}; Timeout: ${r.timeout_count}; HTTP errors: ${r.http_error_count}; Connection errors: ${r.connection_error_count}; Invalid responses: ${r.invalid_response_count}; Parse errors: ${r.parse_error_count}`
                        );
                    }
                    for (const q of qr) {
                        const label = r.external ? (q.status || 'invalid_response').toUpperCase() : (q.correct ? 'CORRECT' : 'WRONG');
                        lines.push(`--- Q${q.id} [${label}] ---`);
                        if (q.category) lines.push(`Category: ${q.category}`);
                        if (r.external && q.finish_reason) lines.push(`Finish reason: ${q.finish_reason}`);
                        if (r.external && (q.reasoning_fields_nonempty || []).length) lines.push(`Reasoning fields: ${q.reasoning_fields_nonempty.join(', ')}`);
                        if (r.external && q.error_message) lines.push(`Error: ${q.error_message}`);
                        lines.push(`Question: ${q.question || ''}`);
                        lines.push(`Expected: ${q.expected}`);
                        lines.push(`Predicted: ${q.predicted}`);
                        lines.push(`Raw response: ${q.raw_response || '(empty)'}`);
                        lines.push(`Time: ${q.time_s}s`);
                        lines.push('');
                    }
                    content = lines.join('\n');
                    mime = 'text/plain';
                }

                const blob = new Blob([content], { type: mime });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = filename;
                a.click();
                URL.revokeObjectURL(url);
            },

            // Log viewer functions
            filteredLogContent() {
                const LEVELS = ['TRACE', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'];
                const minIdx = LEVELS.indexOf(this.logMinLevel);
                if (minIdx <= 0) return this.logContent;
                const levelRe = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} - \S+ - (TRACE|DEBUG|INFO|WARNING|ERROR|CRITICAL) - /;
                let visible = true;
                return this.logContent.split('\n').filter(line => {
                    const m = line.match(levelRe);
                    if (m) visible = LEVELS.indexOf(m[1]) >= minIdx;
                    return visible;
                }).join('\n');
            },

            levelButtonClass(lvl) {
                const LEVELS = ['TRACE', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'];
                const idx = LEVELS.indexOf(lvl);
                const minIdx = LEVELS.indexOf(this.logMinLevel);
                // Levels at or above the minimum are all shown dark so the
                // included range is obvious; the selected minimum keeps the ring.
                if (idx < minIdx) return 'bg-neutral-100 text-neutral-300';
                if (idx === minIdx) return 'bg-neutral-900 text-white';
                return 'bg-neutral-700 text-white';
            },

            async loadLogs() {
                this.logLoading = true;
                this.logError = '';

                try {
                    const params = new URLSearchParams({
                        lines: this.logLines.toString(),
                    });
                    if (this.logFile && this.logFile !== 'server.log') {
                        params.append('file', this.logFile);
                    }

                    const response = await fetch(`/admin/api/logs?${params}`);

                    if (response.ok) {
                        const data = await response.json();
                        this.logContent = data.logs;
                        this.logTotalLines = data.total_lines;
                        this.logAvailableFiles = data.available_files || ['server.log'];
                        this.logLastUpdated = new Date().sult[8 * i + 1] += x * (select(U(0), scale, bool(wb & 0x02)) + bias);
      result[8 * i + 2] += x * (select(U(0), scale, bool(wb & 0x04)) + bias);
      result[8 * i + 3] += x * (select(U(0), scale, bool(wb & 0x08)) + bias);
      result[8 * i + 4] += x * (select(U(0), scale, bool(wb & 0x10)) + bias);
      result[8 * i + 5] += x * (select(U(0), scale, bool(wb & 0x20)) + bias);
      result[8 * i + 6] += x * (select(U(0), scale, bool(wb & 0x40)) + bias);
      result[8 * i + 7] += x * (select(U(0), scale, bool(wb & 0x80)) + bias);
    }
  }

  else if (bits == 2) {
    U s[4] = {scale, scale / 4.0f, scale / 16.0f, scale / 64.0f};
    for (int i = 0; i < (values_per_thread / 4); i++) {
      result[4 * i] += x * (s[0] * (w[i] & 0x03) + bias);
      result[4 * i + 1] += x * (s[1] * (w[i] & 0x0c) + bias);
      result[4 * i + 2] += x * (s[2] * (w[i] & 0x30) + bias);
      result[4 * i + 3] += x * (s[3] * (w[i] & 0xc0) + bias);
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      uint8_t w0 = w[3 * i];
      uint8_t w1 = w[3 * i + 1];
      uint8_t w2 = w[3 * i + 2];

      result[8 * i] += x * ((w0 & 0x7) * scale + bias);
      result[8 * i + 1] += x * (((w0 & 0x38) >> 3) * scale + bias);
      result[8 * i + 2] +=
          x * ((((w0 & 0xc0) >> 6) + ((w1 & 0x1) << 2)) * scale + bias);
      result[8 * i + 3] += x * (((w1 & 0xe) >> 1) * scale + bias);
      result[8 * i + 4] += x * (((w1 & 0x70) >> 4) * scale + bias);
      result[8 * i + 5] +=
          x * ((((w1 & 0x80) >> 7) + ((w2 & 0x3) << 1)) * scale + bias);
      result[8 * i + 6] += x * (((w2 & 0x1c) >> 2) * scale + bias);
      result[8 * i + 7] += x * (((w2 & 0xe0) >> 5) * scale + bias);
    }
  }

  else if (bits == 4) {
    U s[2] = {scale, scale / 16.0f};
    for (int i = 0; i < (values_per_thread / 2); i++) {
      result[2 * i] += x * (s[0] * (w[i] & 0x0f) + bias);
      result[2 * i + 1] += x * (s[1] * (w[i] & 0xf0) + bias);
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      uint8_t w0 = w[5 * i];
      uint8_t w1 = w[5 * i + 1];
      uint8_t w2 = w[5 * i + 2];
      uint8_t w3 = w[5 * i + 3];
      uint8_t w4 = w[5 * i + 4];
      result[8 * i] += x * ((w0 & 0x1f) * scale + bias);
      result[8 * i + 1] +=
          x * ((((w0 & 0xe0) >> 5) + ((w1 & 0x3) << 3)) * scale + bias);
      result[8 * i + 2] += x * (((w1 & 0x7c) >> 2) * scale + bias);
      result[8 * i + 3] +=
          x * ((((w1 & 0x80) >> 7) + ((w2 & 0xf) << 1)) * scale + bias);
      result[8 * i + 4] +=
          x * ((((w2 & 0xf0) >> 4) + ((w3 & 0x1) << 4)) * scale + bias);
      result[8 * i + 5] += x * (((w3 & 0x3e) >> 1) * scale + bias);
      result[8 * i + 6] +=
          x * ((((w3 & 0xc0) >> 6) + ((w4 & 0x7) << 2)) * scale + bias);
      result[8 * i + 7] += x * (((w4 & 0xf8) >> 3) * scale + bias);
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < (values_per_thread / 4); i++) {
      uint8_t w0 = w[3 * i];
      uint8_t w1 = w[3 * i + 1];
      uint8_t w2 = w[3 * i + 2];

      result[4 * i] += x * ((w0 & 0x3f) * scale + bias);
      result[4 * i + 1] +=
          x * ((((w0 >> 6) & 0x03) + ((w1 & 0x0f) << 2)) * scale + bias);
      result[4 * i + 2] +=
          x * ((((w1 >> 4) & 0x0f) + ((w2 & 0x03) << 4)) * scale + bias);
      result[4 * i + 3] += x * (((w2 >> 2) & 0x3f) * scale + bias);
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < values_per_thread; i++) {
      result[i] += x * (scale * w[i] + bias);
    }
  }
}

// Decode one quantized block (scale * q + bias) into w_local. W (the output
// pointer type) serves the threadgroup block loader or a thread-local decode.
template <typename U, int N, int bits, typename W>
inline void dequantize(const device uint8_t* w, U scale, U bias, W w_local) {
  static_assert(
      bits == 1 || bits == 2 || bits == 3 || bits == 4 || bits == 5 ||
          bits == 6 || bits == 8,
      "Template undefined for bits not in {1, 2, 3, 4, 5, 6, 8}");

  if (bits == 1) {
    // 1-bit values are always 0 or 1 — each dequantized eleme
            message = choice.get("message")
            if not isinstance(message, dict):
                raise KeyError("choices[0].message")
        except (KeyError, TypeError) as e:
            raise ExternalEndpointError(
                f"External endpoint returned an unexpected response shape: {e}",
                status="invalid_response",
            ) from e

        content = message.get("content")
        if content is None:
            text = ""
        elif isinstance(content, str):
            text = content
        else:
            raise ExternalEndpointError(
                "External endpoint returned non-text message.content",
                status="invalid_response",
            )

        finish_reason_value = choice.get("finish_reason")
        finish_reason = (
            str(finish_reason_value) if finish_reason_value is not None else None
        )
        reasoning_present, reasoning_nonempty = self._reasoning_diagnostics(message)
        if finish_reason == "length":
            status = "truncated"
        elif not text.strip():
            status = "empty_content"
        else:
            status = "ok"

        usage = data.get("usage") or {}
        if not isinstance(usage, dict):
            usage = {}
        return ChatResult(
            text=text,
            prompt_tokens=self._usage_int(usage, "prompt_tokens"),
            completion_tokens=self._usage_int(usage, "completion_tokens"),
            finish_reason=finish_reason,
            status=status,
            reasoning_fields_present=reasoning_present,
            reasoning_fields_nonempty=reasoning_nonempty,
        )

    async def stream_chat_completion(
        self,
        messages: list[dict],
        max_tokens: int,
        temperature: Optional[float],
    ) -> StreamStats:
        """Send a streaming chat completion request and collect stats.

        Requires the endpoint to return usage via stream_options
        (include_usage); raises ExternalEndpointError otherwise because
        token counts cannot be measured accurately without it.
        """
        body = self._build_body(messages, max_tokens, temperature, stream=True)
        start_time = time.perf_counter()
        first_content_time: Optional[float] = None
        last_content_time: Optional[float] = None
        usage: Optional[dict] = None
        text_parts: list[str] = []

        try:
            async with self._client.stream(
                "POST", self._chat_url, json=body
            ) as response:
                if response.status_code != 200:
                    error_body = await response.aread()
                    raise self._status_error(
                        response.status_code,
                        error_body.decode("utf-8", errors="replace"),
                    )
                async for line in response.aiter_lines():
                    if not line.startswith("data:"):
                        continue
                    payload = line[len("data:") :].strip()
                    if payload == "[DONE]":
                        break
                    try:
                        chunk = json.loads(payload)
                    except ValueError:
                        continue
                    chunk_usage = chunk.get("usage")
                    if chunk_usage:
                        usage = chunk_usage
                    choices = chunk.get("choices") or []
                    if not choices:
                        continue
                    delta = choices[0].get("delta") or {}
                    content = delta.get("content")
                    if content:
                        text_parts.append(content)
                    has_reasoning = any(
                        delta.get(name) for name in _REASONING_FIELD_NAMES
                    )
                    if content or has_reasoning:
                        now = time.perf_counter()
                        if first_content_time is None:
                            first_content_time = now
                        last_content_time = now
        exceptfaultValue: "No tags.",
                                comment: "Empty state in the Tags tab when the upstream API doesn't list any tags")
            )
        } else {
            ScrollView {
                FlowLayout(spacing: 6) {
                    ForEach(tags, id: \.self) { tag in
                        tagPill(tag)
                    }
                }
                .padding(20)
            }
        }
    }

    private func tagPill(_ tag: String) -> some View {
        Text(tag)
            .font(.omlxMono(11))
            .foregroundStyle(theme.textSecondary)
            .padding(.horizontal, 8)
            .padding(.vertical, 4)
            .background(
                Capsule().fill(theme.codeBg)
            )
            .overlay(
                Capsule().strokeBorder(theme.inputBorder, lineWidth: 0.5)
            )
            .textSelection(.enabled)
    }

    private func emptyStateView(symbol: String, message: String) -> some View {
        VStack(spacing: 10) {
            Image(systemName: symbol)
                .font(.system(size: 28, weight: .light))
                .foregroundStyle(theme.textTertiary)
            Text(message)
                .font(.omlxText(13))
                .foregroundStyle(theme.textSecondary)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .padding(24)
    }

    // MARK: Footer (gaps #2 + #3)

    @ViewBuilder
    private func footer(dto: ModelCardDTO) -> some View {
        Divider().overlay(theme.groupBorder)
        HStack(spacing: 10) {
            if let url = target.source.upstreamURL(repoId: target.repoId) {
                Button {
                    NSWorkspace.shared.open(url)
                } label: {
                    Label {
                        Text(viewUpstreamLabel)
                    } icon: {
                        Image(systemName: "arrow.up.right.square")
                            .font(.system(size: 11))
                    }
                    .font(.omlxText(11.5, weight: .medium))
                    .foregroundStyle(theme.textSecondary)
                }
                .buttonStyle(.plain)
            }
            Spacer()
            if dto.isAdapter != true {
                // Adapters can't be downloaded as a runnable model;
                // hide the action entirely so the user doesn't kick
                // off a download that won't load.
                Button {
                    onDownload(target.repoId)
                    dismiss()
                } label: {
                    Label(String(localized: "downloads.card.download",
                                 defaultValue: "Download",
                                 comment: "Primary button in the model card sheet that starts downloading the displayed model"),
                          systemImage: "icloud.and.arrow.down")
                        .labelStyle(.titleAndIcon)
                }
                .buttonStyle(.omlx(.primary))
                .keyboardShortcut(.defaultAction)
            }
        }
        .padding(.horizontal, 18)
        .padding(.vertical, 12)
    }

    /// Source-specific label for the "View on …" link. Localized via
    /// inline interpolation of the source's display name.
    private var viewUpstreamLabel: String {
        String(localized: "downloads.card.view_upstream",
               defaultValue: "View on \(target.source.displayName)",
               comment: "Link button in the model card sheet that opens the upstream model page; placeholder is 'Hugging Face' or 'ModelScope'")
    }

    // MARK: Error / loading

    private var loadingView: some View {
        VStack(spacing: 10) {
            ProgressView()
            Text(String(localized: "downloads.card.loading",
                        defaultValue: "Loading model card…",
                        comment: "Status text shown while the model README is being fetched"))
                .font(.omlxText(11))
                .foregroundStyle(theme.textSecondary)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }

    pritoLocaleTimeString();

                        // Auto-scroll to bottom
                        if (this.logAutoScroll) {
                            this.$nextTick(() => {
                                const textarea = this.$refs.logTextarea;
                                if (textarea) {
                                    textarea.scrollTop = textarea.scrollHeight;
                                }
                            });
                        }
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        this.logError = data.detail || window.t('js.error.load_logs_failed');
                    }
                } catch (err) {
                    console.error('Failed to load logs:', err);
                    this.logError = window.t('js.error.load_logs_failed');
                } finally {
                    this.logLoading = false;
                }
            },

            startLogRefresh() {
                this.stopLogRefresh();  // Clear existing timer

                if (this.logRefreshInterval > 0) {
                    this.logAutoRefresh = true;
                    this._logRefreshTimer = setInterval(() => {
                        this.loadLogs();
                    }, this.logRefreshInterval * 1000);
                }
            },

            stopLogRefresh() {
                if (this._logRefreshTimer) {
                    clearInterval(this._logRefreshTimer);
                    this._logRefreshTimer = null;
                }
                this.logAutoRefresh = false;
            },

            restartLogRefresh() {
                if (this.mainTab === 'logs') {
                    this.startLogRefresh();
                }
            },

            // Parse cache size string (e.g., "10GB") to percent of SSD total capacity
            parseCacheToPercent(cacheStr, totalBytes) {
                if (!cacheStr || cacheStr === 'auto' || !totalBytes || totalBytes === 0) {
                    return 10; // Default 10%
                }

                const match = cacheStr.match(/^(\d+(?:\.\d+)?)\s*(GB|MB|TB)?$/i);
                if (!match) return 10;

                let bytes = parseFloat(match[1]);
                const unit = (match[2] || 'GB').toUpperCase();

                if (unit === 'TB') bytes *= 1024 * 1024 * 1024 * 1024;
                else if (unit === 'GB') bytes *= 1024 * 1024 * 1024;
                else if (unit === 'MB') bytes *= 1024 * 1024;

                const percent = Math.round((bytes / totalBytes) * 100);
                return Math.min(100, percent);
            },

            // Convert percent to cache size string
            percentToCacheString(percent, totalBytes) {
                if (!totalBytes || totalBytes === 0) return 'auto';
                const bytes = Math.floor((percent / 100) * totalBytes);
                const gb = Math.floor(bytes / (1024 * 1024 * 1024));
                return `${gb}GB`;
            },

            // Helper: parse GB from a settings string like "68GB", "1TB", "512MB"
            _parseSettingsGB(val) {
                if (!val) return null;
                const match = val.match(/^(\d+(?:\.\d+)?)\s*(GB|MB|TB)?$/i);
                if (!match) return null;
                let num = parseFloat(match[1]);
                const unit = (match[2] || 'GB').toUpperCase();
                if (unit === 'TB') return Math.round(num * 1024);
                if (unit === 'MB') return Math.round(num / 1024);
                return Math.round(num);
            },

            // Memory guard tier → live hard ceiling (GB) for the selected tier.
            // Mirrors ProcessMemoryEnforcer._get_hard_limit_bytes:
            //   static_ceiling  = total - tier.static_reserve
            //   dynamic_ceiling = omlx_phys + free + inactive + active * ratio
            //   final = min(static, dynamic, metal_cap)
            // The static / dynamic inputs come from thnt is either
    // bias or (scale + bias). No multiply needed; precompute once per group.
    U scale_plus_bias = scale + bias;
    for (int i = 0; i < (N / 8); i++) {
      uint8_t wb = w[i];
      w_local[8 * i + 0] = select(bias, scale_plus_bias, bool(wb & 0x01));
      w_local[8 * i + 1] = select(bias, scale_plus_bias, bool(wb & 0x02));
      w_local[8 * i + 2] = select(bias, scale_plus_bias, bool(wb & 0x04));
      w_local[8 * i + 3] = select(bias, scale_plus_bias, bool(wb & 0x08));
      w_local[8 * i + 4] = select(bias, scale_plus_bias, bool(wb & 0x10));
      w_local[8 * i + 5] = select(bias, scale_plus_bias, bool(wb & 0x20));
      w_local[8 * i + 6] = select(bias, scale_plus_bias, bool(wb & 0x40));
      w_local[8 * i + 7] = select(bias, scale_plus_bias, bool(wb & 0x80));
    }
  }

  else if (bits == 2) {
    // 4-value mux: decoded[q] = scale*q + bias for q in {0,1,2,3}.
    // Use select() pairs (3 instructions per value, no dynamic array index which
    // would spill to device memory on Apple GPU).
    // Precompute all 4 possible decoded values once; compiler dead-code-eliminates
    // values when N is a compile-time constant.
    U d0 = bias;
    U d1 = scale + bias;
    U d2 = fma(U(2), scale, bias);
    U d3 = fma(U(3), scale, bias);
    for (int i = 0; i < (N / 4); i++) {
      uint8_t wb = w[i];
      // Decode each 2-bit field with two select()s: no FP multiply per element.
      auto mux2 = [&](uint8_t q) -> U {
        return select(select(d0, d1, bool(q & 1)), select(d2, d3, bool(q & 1)), bool(q & 2));
      };
      w_local[4 * i + 0] = mux2(wb & 0x03);
      w_local[4 * i + 1] = mux2((wb >> 2) & 0x03);
      w_local[4 * i + 2] = mux2((wb >> 4) & 0x03);
      w_local[4 * i + 3] = mux2((wb >> 6) & 0x03);
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < (N / 8); i++) {
      w_local += 8 * i;
      w += 3 * i;

      w_local[0] = (w[0] & 0x7) * scale + bias;
      w_local[1] = ((w[0] & 0x38) >> 3) * scale + bias;
      w_local[2] = (((w[0] & 0xc0) >> 6) + ((w[1] & 0x1) << 2)) * scale + bias;
      w_local[3] = ((w[1] & 0xe) >> 1) * scale + bias;
      w_local[4] = ((w[1] & 0x70) >> 4) * scale + bias;
      w_local[5] = (((w[1] & 0x80) >> 7) + ((w[2] & 0x3) << 1)) * scale + bias;
      w_local[6] = ((w[2] & 0x1c) >> 2) * scale + bias;
      w_local[7] = ((w[2] & 0xe0) >> 5) * scale + bias;
    }
  }

  else if (bits == 4) {
    U s[2] = {scale, scale / static_cast<U>(16.0f)};
    for (int i = 0; i < (N / 2); i++) {
      w_local[2 * i] = s[0] * (w[i] & 0x0f) + bias;
      w_local[2 * i + 1] = s[1] * (w[i] & 0xf0) + bias;
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < (N / 8); i++) {
      w_local += 8 * i;
      w += 5 * i;

      w_local[0] = (w[0] & 0x1f) * scale + bias;
      w_local[1] = (((w[0] & 0xe0) >> 5) + ((w[1] & 0x3) << 3)) * scale + bias;
      w_local[2] = ((w[1] & 0x7c) >> 2) * scale + bias;
      w_local[3] = (((w[1] & 0x80) >> 7) + ((w[2] & 0xf) << 1)) * scale + bias;
      w_local[4] = (((w[2] & 0xf0) >> 4) + ((w[3] & 0x1) << 4)) * scale + bias;
      w_local[5] = ((w[3] & 0x3e) >> 1) * scale + bias;
      w_local[6] = (((w[3] & 0xc0) >> 6) + ((w[4] & 0x7) << 2)) * scale + bias;
      w_local[7] = ((w[4] & 0xf8) >> 3) * scale + bias;
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < (N / 4); i++) {
      w_local += 4 * i;
      w += 3 * i;
      w_local[0] = (w[0] & 0x3f) * scale + bias;
      w_local[1] = (((w[0] >> 6) & 0x03) + ((w[1] & 0x0f) << 2)) * scale + bias;
      w_local[2] = (((w[1] >> 4) & 0x0f) + ((w[2] & 0x03) << 4)) * scale + bias;
      w_local[3] = ((w[2] >> 2) & 0x3f) * scale + bias;
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < N; i++) {
      w_local[i] = scale * w[i] + bias;
    }
  }
}

template <
    typename T,
    short BROWS,
    short BCOLS,
    short dst_ld,
    short reduction_dim,
    short tgp_size,
    short group_size,
    short bits>
struct QuantizedBlockLoader {
  static_assert(
      BCOLS <= group_size,
      "The group size should be larger than the columns");
  static_assert(
      group_size % BC httpx.HTTPError as e:
            raise self._map_transport_error(e) from e

        end_time = time.perf_counter()

        if (
            usage is None
            or usage.get("prompt_tokens") is None
            or usage.get("completion_tokens") is None
        ):
            raise ExternalEndpointError(
                "External endpoint does not support stream usage "
                "(stream_options.include_usage); cannot measure token counts"
            )
        content_observed = first_content_time is not None
        if first_content_time is None:
            first_content_time = end_time
        if last_content_time is None:
            last_content_time = end_time
        details = usage.get("prompt_tokens_details") or {}
        return StreamStats(
            prompt_tokens=int(usage["prompt_tokens"]),
            completion_tokens=int(usage["completion_tokens"]),
            cached_tokens=int(details.get("cached_tokens") or 0),
            start_time=start_time,
            first_content_time=first_content_time,
            last_content_time=last_content_time,
            end_time=end_time,
            text="".join(text_parts),
            content_observed=content_observed,
        )


@dataclass
class _AdapterOutput:
    """Minimal GenerationOutput stand-in; eval code only reads .text."""

    text: str
    prompt_tokens: int = 0
    completion_tokens: int = 0
    external_status: str = "ok"
    finish_reason: Optional[str] = None
    reasoning_fields_present: tuple[str, ...] = ()
    reasoning_fields_nonempty: tuple[str, ...] = ()
    error_message: str = ""


class ExternalChatAdapter:
    """Duck-typed engine for accuracy benchmarks against an external API.

    eval/base.py only touches engine.model_type and engine.chat(), so this
    adapter maps both onto ExternalAPIClient. Sampling comes from the
    constructor-injected profile: the temperature/penalty defaults that
    _eval_single injects via setdefault cannot be told apart from
    profile-supplied values, so all sampling kwargs are accepted and
    dropped here — "deterministic" sends temperature 0 and
    "model_settings" sends no sampling params (remote server defaults).
    """

    model_type = None
    is_external_api = True

    def __init__(self, client: ExternalAPIClient, sampling_profile: str):
        self._client = client
        self._sampling_profile = sampling_profile

    async def preflight(self) -> None:
        """Validate final-answer compatibility before a paid evaluation."""
        result = await self._client.chat_completion(
            messages=[{"role": "user", "content": "Reply with exactly: OK"}],
            max_tokens=_PREFLIGHT_MAX_TOKENS,
            temperature=None,
        )
        logger.info(
            "External accuracy preflight: finish_reason=%r "
            "reasoning_fields_present=%s reasoning_fields_nonempty=%s",
            result.finish_reason,
            list(result.reasoning_fields_present),
            list(result.reasoning_fields_nonempty),
        )
        if result.status == "truncated":
            raise ExternalEndpointError(
                "External API preflight was truncated (finish_reason=length)",
                status="truncated",
            )
        if result.status == "empty_content":
            if result.reasoning_fields_nonempty:
                raise ExternalEndpointError(
                    "External API connected, but message.content is empty. "
                    "The model may still be in reasoning mode, or the endpoint "
                    "response format may be incompatible with oMLX.",
                    status="empty_content",
                )
            raise ExternalEndpointError(
                "External API connected, but preflight message.content is empty",
                status="empty_content",
            )
        # Some endpoints inline reasoning into message.content as <think>
        # blocks; drop them before checking, the same way eval scoring does.
        answer = re.sub(
            r"<think>.*?</think>", "", result.text, flags=re.DOvate func errorView(message: String) -> some View {
        VStack(spacing: 12) {
            Image(systemName: "exclamationmark.triangle")
                .font(.system(size: 32, weight: .light))
                .foregroundStyle(theme.redDot)
            Text(String(localized: "downloads.card.error",
                        defaultValue: "Couldn't load model card",
                        comment: "Title shown in the model card sheet when the fetch failed"))
                .font(.omlxText(13, weight: .semibold))
                .foregroundStyle(theme.text)
            Text(message)
                .font(.omlxText(11))
                .foregroundStyle(theme.textSecondary)
                .multilineTextAlignment(.center)
                .textSelection(.enabled)
            Button(String(localized: "downloads.card.retry",
                          defaultValue: "Retry",
                          comment: "Retry button shown after the model card fetch failed")) {
                Task { await load() }
            }
            .buttonStyle(.omlx(.primary))
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .padding(24)
    }

    // MARK: Fetch

    private func load() async {
        state = .loading
        do {
            let dto: ModelCardDTO
            switch target.source {
            case .huggingFace:
                dto = try await client.getHFModelCard(repoId: target.repoId)
            case .modelScope:
                dto = try await client.getMSModelCard(modelId: target.repoId)
            }
            state = .loaded(dto)
        } catch {
            state = .failed(error.omlxDescription)
        }
    }

    // MARK: Helpers

    /// Compact-format a count for the metadata counters: 1234 → "1.2K",
    /// 1_500_000 → "1.5M". Mirrors the HTML admin's display so the same
    /// repos show the same numbers on both surfaces.
    private static func compactCount(_ n: Int) -> String {
        switch n {
        case 1_000_000_000...:
            return String(format: "%.1fB", Double(n) / 1_000_000_000)
        case 1_000_000...:
            return String(format: "%.1fM", Double(n) / 1_000_000)
        case 1_000...:
            return String(format: "%.1fK", Double(n) / 1_000)
        default:
            return String(n)
        }
    }
}

// `FlowLayout` (used by the Tags tab) lives in ProfileViews.swift —
// reused here for consistency. If it ever needs to specialize for the
// model-card sheet, prefer extending the shared type over forking.


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/ModelSettingsScreen.swift =====

// PR 8 — per-model settings drilled into from ModelsScreen via the chevron.
//
// Sections (segmented at the top):
//   • Profiles  — list per-model profiles + create / delete / apply,
//                  list templates (read-only) + apply a template as a profile
//   • Basic     — alias, model type, context window, max tokens, sampling
//                  defaults (temperature, top_p, top_k, min_p,
//                  repetition_penalty, presence_penalty), TTL
//   • Advanced  — enable_thinking, thinking budget, limit tool result tokens,
//                  force sampling, pin in memory
//
// Aliases (the design's 4th tab) is omitted: server has no /api/aliases
// endpoint and `model_alias` is singular. Keeping the surface honest.
//
// Saves on every committed edit (Popup change / TextField submit / Toggle
// flip), no explicit Save button — same UX as ServerScreen. The design's
// Save / Cancel / Load Defaults buttons live as a top-right toolbar that
// only does navigation back to Models.

import SwiftUI

struct ModelSettingsScreen: View {
    let modelID: String

    @Environment(AppServices.self) private var services
    @State private var vm = ModelSettingsScreenVM()

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            Header(model: vm.model)

            SectionPicker(selection: $vm.section)

            switch vm.section {
            case .profiles:
                ProfilesTab(
                    vm: vm,
       e global-settings
            // response and reflect the moment that response was fetched.
            // Warning shown below the breakdown when the kernel
            // iogpu.wired_limit_mb is lower than what oMLX asked Metal
            // to allow at start. Returns an HTML string with the exact
            // sysctl command the user can paste into Terminal, or "" when
            // the kernel cap is fine.
            // True when the kernel iogpu.wired_limit_mb (or Apple default
            // working set) caps oMLX below its desired static ceiling.
            get memoryGuardShowWiredLimitWarning() {
                const sys = this.globalSettings.system || {};
                const kernelBytes = sys.iogpu_wired_limit_bytes || 0;
                const requestedBytes = sys.omlx_wired_limit_request_bytes || 0;
                if (kernelBytes <= 0 || requestedBytes <= 0) return false;
                return kernelBytes < requestedBytes;
            },

            // Red bold warning text (no copy button). The button is a
            // separate sibling in the template so Alpine can wire @click.
            get memoryGuardWiredLimitWarningHTML() {
                if (!this.memoryGuardShowWiredLimitWarning) return '';
                const sys = this.globalSettings.system;
                const kernelGB = (sys.iogpu_wired_limit_bytes / (1024 ** 3)).toFixed(1);
                const template = window.t('settings.resource.guard_tier.wired_limit_warning');
                return template.replaceAll(
                    '{kernel}',
                    `<strong>${kernelGB} GB</strong>`,
                );
            },

            // The sysctl command rendered in the dark bold <code> chip.
            get memoryGuardWiredLimitCommand() {
                if (!this.memoryGuardShowWiredLimitWarning) return '';
                const requested = this.globalSettings.system.omlx_wired_limit_request_bytes;
                const requestedMB = Math.ceil(requested / (1024 ** 2));
                return `sudo sysctl iogpu.wired_limit_mb=${requestedMB}`;
            },

            // 2-second "Copied!" affordance after the clipboard button is
            // pressed. Reset by the same setTimeout so it's harmless if
            // the user clicks rapidly.
            wiredLimitCopied: false,

            copyWiredLimitCommand() {
                const text = this.memoryGuardWiredLimitCommand;
                if (!text) return;
                const onSuccess = () => {
                    this.wiredLimitCopied = true;
                    setTimeout(() => { this.wiredLimitCopied = false; }, 2000);
                };
                if (navigator.clipboard && navigator.clipboard.writeText) {
                    navigator.clipboard.writeText(text).then(onSuccess).catch(() => {
                        onSuccess();
                    });
                } else {
                    onSuccess();
                }
            },

            // Description text shown next to the Memory guard tier dropdown.
            // safe / balanced / aggressive get a "free + inactive + N% of
            // active (via macOS reclaim_method)" sentence. custom shows the
            // user-supplied ceiling.
            get memoryGuardTierDescription() {
                const tier = this.globalSettings.memory?.memory_guard_tier || 'balanced';
                const tierLabel = window.t('settings.resource.guard_tier.' + tier);
                if (tier === 'custom') {
                    const gb = Number(
                        this.globalSettings.memory?.memory_guard_custom_ceiling_gb || 0
                    ).toFixed(1);
                    return window
                        .t('settings.resource.guard_tier.description_custom')
                        .replace('{custom_gb}', gb);
                }
                const pct = { safe: 20, balanced: 50, aggressive: 80 }[tier] ?? 50;
                const method = window.t(
                    'settings.resource.guard_tier.reclaim_method.' + tier
                );
                return window
          OLS == 0,
      "The group size should be divisible by the columns");
  static_assert(
      bits == 1 || bits == 2 || bits == 3 || bits == 4 || bits == 5 ||
          bits == 6 || bits == 8,
      "Template undefined for bits not in {1, 2, 3, 4, 5, 6, 8}");

  MLX_MTL_CONST short pack_factor = get_pack_factor<bits, 8>();
  MLX_MTL_CONST short bytes_per_pack = get_bytes_per_pack<bits>();
  MLX_MTL_CONST short BCOLS_PACKED = BCOLS / pack_factor;
  MLX_MTL_CONST short n_reads =
      (BCOLS_PACKED * BROWS < tgp_size) ? 1 : (BCOLS_PACKED * BROWS) / tgp_size;
  MLX_MTL_CONST short group_steps = group_size / BCOLS;

  const int src_ld;
  const int tile_stride;
  short group_step_cnt;
  const int group_stride;

  const short thread_idx;
  const short bi;
  const short bj;

  threadgroup T* dst;
  const device uint8_t* src;
  const device T* scales;
  const device T* biases;

  QuantizedBlockLoader(
      const device uint8_t* src_,
      const device T* scales_,
      const device T* biases_,
      const int src_ld_,
      threadgroup T* dst_,
      ushort simd_group_id [[simdgroup_index_in_threadgroup]],
      ushort simd_lane_id [[thread_index_in_simdgroup]])
      : src_ld(src_ld_),
        tile_stride(
            reduction_dim ? BCOLS_PACKED * bytes_per_pack
                          : BROWS * src_ld * bytes_per_pack / pack_factor),
        group_step_cnt(0),
        group_stride(BROWS * src_ld / group_size),
        thread_idx(simd_group_id * 32 + simd_lane_id),
        bi(n_reads * thread_idx / BCOLS_PACKED),
        bj((n_reads * thread_idx) % BCOLS_PACKED),
        dst(dst_ + bi * dst_ld + bj * pack_factor),
        src(src_ + bi * src_ld * bytes_per_pack / pack_factor +
            bj * bytes_per_pack),
        scales(scales_ + bi * src_ld / group_size),
        biases(biases_ + bi * src_ld / group_size) {}

  void load_unsafe() const {
    if (BCOLS_PACKED * BROWS < tgp_size && bi >= BROWS) {
      return;
    }

    T scale = *scales;
    T bias = *biases;
    for (int i = 0; i < n_reads; i++) {
      dequantize<T, pack_factor, bits>(
          src + i * bytes_per_pack, scale, bias, dst + i * pack_factor);
    }
  }

  void load_safe(short2 src_tile_dim) const {
    if (BCOLS_PACKED * BROWS < tgp_size && bi >= BROWS) {
      return;
    }

    if (reduction_dim == 1 && bi >= src_tile_dim.x) {
      for (int i = 0; i < n_reads * pack_factor; i++) {
        dst[i] = T(0);
      }
      return;
    }

    if (reduction_dim == 0 && bi >= src_tile_dim.y) {
      for (int i = 0; i < n_reads * pack_factor; i++) {
        dst[i] = T(0);
      }
      return;
    }

    T scale = *scales;
    T bias = *biases;
    for (int i = 0; i < n_reads; i++) {
      dequantize<T, pack_factor, bits>(
          (device uint8_t*)(src + i * bytes_per_pack),
          scale,
          bias,
          dst + i * pack_factor);
    }
  }

  void next() {
    src += tile_stride;
    if (reduction_dim == 1) {
      if (group_steps > 1) {
        group_step_cnt++;
        if (group_step_cnt == group_steps) {
          group_step_cnt = 0;
          scales++;
          biases++;
        }
      } else {
        scales++;
        biases++;
      }
    } else {
      scales += group_stride;
      biases += group_stride;
    }
  }
};

template <typename T, int group_size, int bits, int D>
METAL_FUNC void qmv_quad_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    constant int& in_vec_size,
    const constant int& out_vec_size,
    uint3 tid [[threadgroup_position_in_grid]],
    uint quad_gid [[quadgroup_index_in_threadgroup]],
    uint quad_lid [[thread_index_in_quadgroup]]) {
  constexpr int quads_per_simd = SIMD_SIZE / QUAD_SIZE;
  constexpr int pack_factor = 32 / bits;
  constexpr int values_per_thread = D / QUAD_SIZE;
  constexpr int packs_per_thread = values_per_thread / pack_factor;
  constexpr int scale_step_per_thread = group_size / values_per_thread;
  constexpr int results_per_quadgroup = 8;

  typedef float U;

  thread U x_thread[values_per_thread];
  threTALL
        ).strip()
        # Accept a leading OK with trailing punctuation or extra words
        # (OK. / Okay / OK!) so a compliant endpoint is not rejected over
        # formatting. A genuinely wrong or negated reply (NOT OK) still fails.
        if not answer.upper().startswith("OK"):
            raise ExternalEndpointError(
                "External API preflight response did not start with OK in "
                "message.content",
                status="parse_error",
            )

    async def chat(
        self,
        messages: list[dict],
        max_tokens: int = 256,
        **kwargs: Any,
    ) -> _AdapterOutput:
        temperature = 0.0 if self._sampling_profile == "deterministic" else None
        try:
            result = await self._client.chat_completion(
                messages=messages,
                max_tokens=max_tokens,
                temperature=temperature,
            )
        except ExternalEndpointError as exc:
            return _AdapterOutput(
                text="",
                external_status=exc.status,
                error_message=str(exc),
            )
        return _AdapterOutput(
            text=result.text,
            prompt_tokens=result.prompt_tokens,
            completion_tokens=result.completion_tokens,
            external_status=result.status,
            finish_reason=result.finish_reason,
            reasoning_fields_present=result.reasoning_fields_present,
            reasoning_fields_nonempty=result.reasoning_fields_nonempty,
        )


# ===== FILE: omlx/admin/hf_downloader.py =====

# SPDX-License-Identifier: Apache-2.0
"""HuggingFace model downloader for oMLX admin panel.

Downloads models from HuggingFace Hub using huggingface_hub's snapshot_download
with directory-size-based progress polling.
"""

import asyncio
import enum
import logging
import shutil
import time
import uuid
from dataclasses import dataclass, field
from pathlib import Path
from typing import Callable, Optional
from urllib.parse import urlparse

from huggingface_hub import HfApi, hf_hub_download, snapshot_download
from huggingface_hub.utils import (
    EntryNotFoundError,
    GatedRepoError,
    HfHubHTTPError,
    RepositoryNotFoundError,
)
from huggingface_hub.utils import tqdm as _hf_tqdm

# Private-module import; the pyproject floor (huggingface-hub>=1.19.0)
# guarantees it exists. Re-verify the symbol when bumping the hub version.
from huggingface_hub.utils._xet import abort_xet_session

logger = logging.getLogger(__name__)

# Timeout for HuggingFace API calls (seconds).
# Prevents server from hanging when HF is unreachable.
_HF_API_TIMEOUT = 10

# Seconds with no download progress before considering the download stalled.
_STALL_TIMEOUT = 300

# Cache of (configured_endpoint -> resolved_endpoint) so we only probe each
# endpoint once per process lifetime. Mirrors like hf-mirror.com permanently
# 308-redirect to huggingface.co when accessed from IPs outside their region;
# huggingface_hub does NOT follow those cross-origin 308s during HEAD probes,
# so downloads fail. We resolve the redirect chain upfront and pin HfApi to
# the final origin.
_endpoint_resolution_cache: dict[str, str] = {}


def _resolve_endpoint(endpoint: str) -> str:
    """Follow permanent (301/308) cross-origin redirects on `endpoint`.

    Returns the final origin (scheme://host[:port]) the endpoint resolves to.
    Used to work around `huggingface_hub`'s inability to follow cross-origin
    308 redirects during file-download HEAD probes.

    Probes a known-stable HF API path (`/api/models/gpt2`) with HEAD; if the
    server returns a 301/308 with a Location pointing at a different host,
    the redirected origin is returned (and cached). Network errors fall back
    to the original endpoint.
    """
    endpoint = endpoint.rstrip("/")
    if endpoint in _endpoint_resolution_cache:
        return _endpoint_resolution_cache[endpoint]

    try:
        import httpx
    except ImportError:
        return endpoint

    probe = f"{endpoint}/api/models/gpt2"
    original_host = urlparse(endpoint).netloc
              presetStore: services.presetBundle,
                    client: services.client,
                    serverDefaults: vm.serverDefaultSampling,
                    // Deep-link to the Server tab's Default Profile
                    // section. Setting the anchor *before* the section
                    // means ContentScaffold's `.task(id:)` sees both
                    // pieces in one go and scrolls without a noop pass.
                    onEditServer: {
                        services.requestedServerAnchor = .defaultProfile
                        services.requestedSection = .server
                    }
                )
            case .basic:
                BasicTab(vm: vm, client: services.client)
            case .advanced:
                AdvancedTab(vm: vm, client: services.client)
            }

            if let error = vm.lastError {
                Text(error)
                    .font(.omlxText(11))
                    .foregroundStyle(.red)
                    .padding(.horizontal, 18)
                    .padding(.top, 8)
            }
        }
        .toolbar {
            ToolbarItem(placement: .navigation) {
                backButton
            }
        }
        .task(id: modelID) { await vm.load(modelID: modelID, client: services.client) }
    }

    @ViewBuilder
    private var backButton: some View {
        Button {
            services.modelDetailID = nil
        } label: {
            Label(String(localized: "settings.header.back_to_models",
                         defaultValue: "Back to Models",
                         comment: "Back button label at the top of the per-model settings screen"),
                  systemImage: "chevron.left")
                .labelStyle(.iconOnly)
        }
    }
}

// MARK: - Header

private struct Header: View {
    let model: ModelDTO?
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        HStack(spacing: 12) {
            Squircle(systemSymbol: "cpu", size: 44, gradient: SquircleGradient.models)
            VStack(alignment: .leading, spacing: 2) {
                HStack(spacing: 4) {
                    Text(model?.displayTitle ?? "—")
                        .font(.omlxText(17, weight: .semibold))
                        .foregroundStyle(theme.text)
                        .lineLimit(1)
                        .truncationMode(.tail)
                    if let id = model?.id {
                        CopyIconButton(value: id)
                    }
                }
                if let m = model {
                    Text("\(m.id) · \(m.estimatedSizeFormatted ?? formatBytes(m.estimatedSize))")
                        .font(.omlxMono(11))
                        .foregroundStyle(theme.textSecondary)
                        .lineLimit(1)
                        .truncationMode(.middle)
                }
            }
            .layoutPriority(1)
            Spacer()
        }
        .padding(.horizontal, 14)
        .padding(.bottom, 10)
    }
}

// MARK: - Section picker

private struct SectionPicker: View {
    @Binding var selection: ModelSettingsScreenVM.Section

    var body: some View {
        HStack {
            Segmented(
                selection: $selection,
                options: ModelSettingsScreenVM.Section.allCases.map {
                    ($0, $0.label)
                }
            )
            Spacer()
        }
        .padding(.horizontal, 14)
        .padding(.vertical, 6)
    }
}

// MARK: - Profiles tab

private struct ProfilesTab: View {
    var vm: ModelSettingsScreenVM
    /// Source of `.preset` chips — the shipped JSON bundle, refreshable
    /// from omlx.ai via `POST /api/presets/refresh`. Replaces the legacy
    /// `vm.templates.filter { isBuiltin }` source after Phase 1 retired
    /// the server-side builtin templates.
    let presetStore: PresetBundleStore
    let client: OMLXClient
    /// Optional binding to a Server-Defaults DTO surfaced read-only at
    /// the bottom of the tab. Lives on the parent (a `@State`-
    /// owned VM) so Phase 3's Server screen and          .t('settings.resource.guard_tier.description_template')
                    .replace('{tier}', tierLabel)
                    .replace('{active_pct}', pct)
                    .replace('{reclaim_method}', method);
            },

            // Breakdown line. For ratio tiers: `Free X, inactive Y, active Z
            // × N% = R → ceiling C`. For custom: `Custom ceiling X GB →
            // effective ceiling C` (after clamp by static / metal cap).
            get memoryGuardBreakdownHTML() {
                const sys = this.globalSettings.system || {};
                const GB = 1024 ** 3;
                const tier = this.globalSettings.memory?.memory_guard_tier || 'balanced';
                const fmt = (gb) => Number(gb).toFixed(1);
                const bold = (gb) => `<strong>${fmt(gb)} GB</strong>`;

                // Static / metal cap for the final clamp shown to the user.
                // The small-system threshold must track
                // ProcessMemoryEnforcer._SMALL_SYSTEM_THRESHOLD (24 GB): under
                // it the server reserves a flat 4 GB regardless of tier. This
                // read 16 and so understated the static ceiling by up to 4 GB
                // on every 16-23 GB Mac.
                const totalGB = (sys.total_memory_bytes || 0) / GB;
                const staticReserveGB =
                    tier === 'custom'
                        ? 2
                        : totalGB < 24
                            ? 4
                            : { safe: 8, balanced: 6, aggressive: 4 }[tier] ?? 6;
                const staticCeiling = Math.max(0, totalGB - staticReserveGB);
                const metalCapGB = (sys.iogpu_wired_limit_bytes || 0) / GB;

                // Helper: is the kernel iogpu.wired_limit_mb the smallest
                // of the three candidates? When yes we swap "→ ceiling" for
                // "/ effective ceiling X (kernel limit)" so the user knows
                // why the value isn't what their tier math suggested.
                const kernelBinds = (candidates, finalCeiling) =>
                    metalCapGB > 0 &&
                    Math.abs(metalCapGB - finalCeiling) < 1e-6 &&
                    candidates.every((c) => c >= metalCapGB - 1e-6);

                if (tier === 'custom') {
                    const custom = Number(
                        this.globalSettings.memory?.memory_guard_custom_ceiling_gb || 0
                    );
                    const candidates = [custom, staticCeiling];
                    if (metalCapGB > 0) candidates.push(metalCapGB);
                    const ceiling = Math.max(0, Math.min(...candidates));
                    const tmpl = kernelBinds([custom, staticCeiling], ceiling)
                        ? 'settings.resource.guard_tier.breakdown_custom_kernel_limit'
                        : 'settings.resource.guard_tier.breakdown_custom';
                    return window
                        .t(tmpl)
                        .replace('{custom_gb}', bold(custom))
                        .replace('{ceiling}', bold(ceiling));
                }

                const freeGB = (sys.free_memory_bytes || 0) / GB;
                const inactiveGB = (sys.inactive_memory_bytes || 0) / GB;
                const activeGB = (sys.active_memory_bytes || 0) / GB;
                const ratio = { safe: 0.2, balanced: 0.5, aggressive: 0.8 }[tier] ?? 0.5;
                const pct = Math.round(ratio * 100);
                const reclaim = activeGB * ratio;
                const omlxGB = (sys.omlx_phys_footprint_bytes || 0) / GB;
                const dynamicCeiling = omlxGB + freeGB + inactiveGB + reclaim;
                const candidates = [dynamicCeiling, staticCeiling];
                if (metalCapGB > 0) candidates.push(metalCapGB);
                const ceiling = Math.max(0, Math.min(...candidates));
                const tmpl = kernelBinds([dynamicCeiling, staticCeiling], ceiling)
                    ? 'settings.resource.guard_tier.breakdown_kernel_limit'
                    : 'settings.resource.guard_tier.breakdowad U result[results_per_quadgroup] = {0};

  // Adjust positions
  const int in_vec_size_w = in_vec_size / pack_factor;
  const int in_vec_size_g = in_vec_size / group_size;
  const int out_row = tid.y * quads_per_simd * results_per_quadgroup + quad_gid;

  w += out_row * in_vec_size_w + quad_lid * packs_per_thread;
  scales += out_row * in_vec_size_g + quad_lid / scale_step_per_thread;
  biases += out_row * in_vec_size_g + quad_lid / scale_step_per_thread;
  x += tid.x * in_vec_size + quad_lid * values_per_thread;
  y += tid.x * out_vec_size + out_row;

  U sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);

  for (int row = 0; row < results_per_quadgroup; row++) {
    auto wl = (const device uint8_t*)(w + row * in_vec_size_w * quads_per_simd);
    const device T* sl = scales + row * in_vec_size_g * quads_per_simd;
    const device T* bl = biases + row * in_vec_size_g * quads_per_simd;

    U s = sl[0];
    U b = bl[0];
    if (row * quads_per_simd + out_row < out_vec_size) {
      result[row] += qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
    }
  }

  for (int row = 0; row < results_per_quadgroup; row++) {
    result[row] = quad_sum(result[row]);
    if (quad_lid == 0 && row * quads_per_simd + out_row < out_vec_size) {
      y[row * quads_per_simd] = static_cast<T>(result[row]);
    }
  }
}

template <typename T, int group_size, int bits, bool symmetric = false>
METAL_FUNC void qmv_fast_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  constexpr int packs_per_thread = bits <= 2 ? 1 : 2;  // 1-bit: 1 pack (vpt=32) for occupancy
  constexpr int num_simdgroups = 4;
  constexpr int results_per_simdgroup = 4;
  constexpr int pack_factor = get_pack_factor<bits, 32>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits, 32>();
  constexpr int values_per_thread = pack_factor * packs_per_thread;
  constexpr int block_size = values_per_thread * SIMD_SIZE;
  constexpr int scale_step_per_thread = group_size / values_per_thread;

  const device uint8_t* ws = (const device uint8_t*)w;

  typedef float U;

  thread U x_thread[values_per_thread];
  thread U result[results_per_simdgroup] = {0};

  // Adjust positions
  const int in_vec_size_w = in_vec_size * bytes_per_pack / pack_factor;
  const int in_vec_size_g = in_vec_size / group_size;
  const int out_row = tid.y * (num_simdgroups * results_per_simdgroup) +
      simd_gid * results_per_simdgroup;

  ws += out_row * in_vec_size_w + simd_lid * packs_per_thread * bytes_per_pack;
  scales += out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
  if constexpr (!symmetric) {
    biases += out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
  }
  x += tid.x * in_vec_size + simd_lid * values_per_thread;
  y += tid.x * out_vec_size + out_row;

  const int aligned_end = (in_vec_size / block_size) * block_size;

  for (int k = 0; k < aligned_end; k += block_size) {
    U sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);

    for (int row = 0; row < results_per_simdgroup; row++) {
      auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
      const device T* sl = scales + row * in_vec_size_g;

      U s = sl[0];
      U b;
      if constexpr (symmetric) {
        // I-B: bias = -scale * ratio; no DRAM load needed.
        // bits=1: bias = -scale/2 (q in {0,1}, dequant = scale*(q-0.5))
        // bits=2: bias = -scale   (q in {0,1,2}, dequant = scale*(q-1))
        b = -s * U(bits == 1 ? 0.5f : 1.0f);
      } else {
        const device T* bl = biases + row * in_vec_size_g;
        b = bl[0];
      }
      result[row] += qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
    }

    ws += block_size * bytes_per_pack / pack_factor;
    scales += block_size / group_size;
    if constexpr (!symmetric) {
      bia   resolved = endpoint
    try:
        with httpx.Client(follow_redirects=False, timeout=5.0) as client:
            r = client.head(probe)
            # Walk up to 3 permanent hops; stop on first non-permanent status.
            hops = 0
            current_url = probe
            while r.status_code in (301, 308) and "location" in r.headers:
                hops += 1
                if hops > 3:
                    break
                location = r.headers["location"]
                if location.startswith("/"):
                    # Relative redirect — same origin, no rewrite needed.
                    break
                target = urlparse(location)
                if not target.netloc:
                    break
                if target.netloc != original_host:
                    # Cross-origin permanent redirect: rewrite the endpoint.
                    port = f":{target.port}" if target.port else ""
                    resolved = f"{target.scheme}://{target.hostname}{port}"
                    original_host = target.netloc
                current_url = location
                r = client.head(current_url)
    except Exception as e:  # noqa: BLE001 — probe is best-effort
        logger.debug(f"HF endpoint probe failed for {endpoint}: {e}")
        return endpoint

    if resolved != endpoint:
        logger.info(
            f"HuggingFace endpoint {endpoint} permanently redirects to "
            f"{resolved}; using resolved origin for downloads."
        )
    _endpoint_resolution_cache[endpoint] = resolved
    return resolved


class _DownloadCancelled(Exception):
    """Raised inside the download thread to interrupt a cancelled download."""


def _make_cancellable_tqdm(should_cancel: Callable[[], bool]) -> type:
    """Build a tqdm subclass that aborts the download when cancelled.

    huggingface_hub's http_get calls ``progress.update(len(chunk))`` once per
    downloaded chunk (DOWNLOAD_CHUNK_SIZE, 10MB). A running thread can't be
    force-stopped and snapshot_download takes no cancel token, so we cooperate
    from the progress callback: raising here unwinds the download thread
    cleanly within one chunk, releasing its buffers and connection.

    Note: this only interrupts the Python http_get path, which xet-less repos
    and mirror endpoints still use. On the xet path the Rust side defers a
    callback exception until the whole transfer finishes (issue #1322), so
    cancellation there is driven by ``abort_xet_session()`` instead; this
    class is kept as the raise-on-next-chunk backstop for http_get.
    """

    class _CancellableTqdm(_hf_tqdm):
        def update(self, n=1):
            if should_cancel():
                raise _DownloadCancelled()
            return super().update(n)

    return _CancellableTqdm


def _get_hf_api() -> tuple[HfApi, str | None]:
    """Create HfApi instance with configured endpoint.

    Only the admin UI's `huggingface.endpoint` setting is honored here.
    When that's empty, return `HfApi()` with no explicit endpoint so
    `huggingface_hub` falls back to its own resolution (which already
    honors the `HF_ENDPOINT` env var). The configured endpoint, when
    present, is run through `_resolve_endpoint()` to follow permanent
    cross-origin redirects (e.g. hf-mirror.com → huggingface.co from
    non-CN IPs) so downstream HF library code sees a stable origin.

    Returns:
        Tuple of (HfApi instance, endpoint URL or None).
    """
    endpoint: str | None = None
    try:
        from ..settings import get_settings

        endpoint = get_settings().huggingface.endpoint or None
    except (RuntimeError, AttributeError):
        endpoint = None

    if endpoint:
        resolved = _resolve_endpoint(endpoint)
        return HfApi(endpoint=resolved), resolved
    return HfApi(), None


def _list_models_stale_token_fallback(api: HfApi, kwargs: dict) -> tuple[list, bool]:
    """Drain list_models, retrying anonymously when the stored token is rejected.

    huggingface_hub attaches the locally stored credential (HF_TOKEN env var or
    the hf auth login tok this tab share state.
    var serverDefaults: GlobalSettingsDTO.SamplingDTO?
    /// Action handler for "Edit on Server →" link in the Server
    /// Defaults section. Lifted by the parent so we don't introduce a
    /// hard dep on AppServices from inside this view.
    var onEditServer: () -> Void

    /// Currently previewed chip (overrides the active-state detail card).
    @State private var preview: ActiveProfileState.NamedProfileRef? = nil
    /// Save-as popover state. Non-nil → popover visible. Pre-set + switchable
    /// scope per chat2.md decisions.
    @State private var saveAsName: String = ""
    @State private var saveAsScope: ProfileScope = .global
    @State private var saveAsOpen: Bool = false

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            // Active state banner — three variants (working / named / defaults).
            ActiveProfileBanner(
                state: vm.activeProfileState,
                isSlim: false,
                onUpdateBasedOn: {
                    if case .working(let basedOn) = vm.activeProfileState, let basedOn {
                        Task {
                            await vm.updateProfileWithWorking(
                                scope: basedOn.scope, name: basedOn.name, client: client
                            )
                        }
                    }
                },
                onSaveAsNew: { openSaveAs(scope: .global) },
                onRevert: {
                    Task { await vm.revertWorking(client: client) }
                }
            )

            if saveAsOpen {
                SaveAsPopover(
                    name: $saveAsName,
                    scope: $saveAsScope,
                    onCommit: {
                        Task {
                            await vm.saveWorkingAs(
                                scope: saveAsScope, name: saveAsName, client: client
                            )
                            saveAsOpen = false
                        }
                    },
                    onCancel: { saveAsOpen = false }
                )
            }

            ProfileGroup(
                scope: .preset,
                label: String(localized: "settings.profiles.preset.label",
                              defaultValue: "Preset Profiles",
                              comment: "Section label above the bundled preset profiles chip group"),
                names: presetStore.entries.map(\.name),
                activeName: vm.activeProfileState.activeName(in: .preset),
                basedOnName: vm.activeProfileState.basedOnName(in: .preset),
                previewName: preview?.scope == .preset ? preview?.name : nil,
                canSaveCurrent: false,
                onSelect: { previewChip(scope: .preset, name: $0) },
                onSaveCurrent: { },
                onRefresh: {
                    Task { await presetStore.refresh(client: client) }
                },
                isRefreshing: presetStore.isRefreshing
            )

            ProfileGroup(
                scope: .global,
                label: String(localized: "settings.profiles.global.label",
                              defaultValue: "Global Profiles",
                              comment: "Section label above the user-defined global profile templates chip group"),
                names: vm.templates.filter { $0.templateScope == .global }.map(\.name),
                activeName: vm.activeProfileState.activeName(in: .global),
                basedOnName: vm.activeProfileState.basedOnName(in: .global),
                previewName: preview?.scope == .global ? preview?.name : nil,
                canSaveCurrent: vm.profileDirty,
                onSelect: { previewChip(scope: .global, name: $0) },
                onSaveCurrent: { openSaveAs(scope: .global) },
                onRename: { original, renamed in
                    Task { await vm.renameTemplate(from: original, to: renamed, client: client) }
                }
            )

            ProfileGroup(
                scope: .mn';
                return window
                    .t(tmpl)
                    .replace('{free}', bold(freeGB))
                    .replace('{inactive}', bold(inactiveGB))
                    .replace('{active}', bold(activeGB))
                    .replace(/{active_pct}/g, pct)
                    .replace('{reclaim}', bold(reclaim))
                    .replace('{ceiling}', bold(ceiling));
            },

            // Computed hot cache size in GB (for manual input)
            get hotCacheSizeGB() {
                const val = this.globalSettings.cache?.hot_cache_max_size;
                if (val && val !== '0') {
                    const parsed = this._parseSettingsGB(val);
                    if (parsed !== null) return parsed;
                }
                if (this.hotCachePercent === 0) return 0;
                const totalBytes = this.globalSettings.system?.total_memory_bytes || 0;
                const bytes = Math.floor((this.hotCachePercent / 100) * totalBytes);
                return Math.floor(bytes / (1024 * 1024 * 1024));
            },

            // Update hot cache from manual GB input
            updateHotCacheFromInput(gbValue) {
                const gb = parseInt(gbValue) || 0;
                if (gb === 0) {
                    this.hotCachePercent = 0;
                    this.globalSettings.cache.hot_cache_max_size = '0';
                } else {
                    const totalBytes = this.globalSettings.system?.total_memory_bytes || 0;
                    if (totalBytes > 0) {
                        const bytes = gb * 1024 * 1024 * 1024;
                        this.hotCachePercent = Math.min(50, Math.max(1, Math.round((bytes / totalBytes) * 100)));
                    }
                    this.globalSettings.cache.hot_cache_max_size = `${gb}GB`;
                }
            },

            // Computed cache size in GB (for manual input)
            get cacheSizeGB() {
                const val = this.globalSettings.cache?.ssd_cache_max_size;
                if (val && val !== 'auto') {
                    const parsed = this._parseSettingsGB(val);
                    if (parsed !== null) return parsed;
                }
                const totalBytes = this.globalSettings.system?.ssd_total_bytes || 0;
                if (!totalBytes) return 0;
                const bytes = Math.floor((this.cachePercent / 100) * totalBytes);
                return Math.round(bytes / (1024 * 1024 * 1024));
            },

            // Update cache from slider
            updateCacheFromSlider() {
                const totalBytes = this.globalSettings.system?.ssd_total_bytes || 0;
                this.globalSettings.cache.ssd_cache_max_size = this.percentToCacheString(this.cachePercent, totalBytes);
            },

            // Update cache from manual GB input
            updateCacheFromInput(gbValue) {
                const gb = parseInt(gbValue) || 0;
                this.globalSettings.cache.ssd_cache_max_size = `${gb}GB`;

                // Update percent slider
                const totalBytes = this.globalSettings.system?.ssd_total_bytes || 0;
                if (totalBytes > 0) {
                    const bytes = gb * 1024 * 1024 * 1024;
                    this.cachePercent = Math.min(100, Math.round((bytes / totalBytes) * 100));
                }
            },

            // Parse hot cache size string to percent of total memory
            normalizeHotCacheMaxSize(value) {
                const normalized = String(value ?? '').trim();
                if (!normalized || normalized.toLowerCase() === 'auto') return '0';
                return normalized;
            },

            parseHotCacheToPercent(hotCacheStr, totalBytes) {
                if (!hotCacheStr || hotCacheStr === '0' || !totalBytes || totalBytes === 0) {
                    return 0;
                }
                const match = hotCacheStr.match(/^(\d+(?:\.\d+)?)\s*(GB|MB|TB)?$/i);
                if (!match) return 0;

                let bytes = parseFloat(match[1]);
                const unit = (match[2] ||ses += block_size / group_size;
    }
    x += block_size;
  }

  if (aligned_end < in_vec_size) {
    bool in_bounds = (aligned_end + simd_lid * values_per_thread) < in_vec_size;
    U sum = 0;
    if (in_bounds) {
      sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);
    } else {
      for (int i = 0; i < values_per_thread; i++)
        x_thread[i] = 0;
    }

    for (int row = 0; row < results_per_simdgroup; row++) {
      auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
      const device T* sl = scales + row * in_vec_size_g;

      U s = in_bounds ? (U)sl[0] : (U)0;
      U b;
      if constexpr (symmetric) {
        b = -s * U(bits == 1 ? 0.5f : 1.0f);
      } else {
        const device T* bl = biases + row * in_vec_size_g;
        b = in_bounds ? (U)bl[0] : (U)0;
      }
      result[row] += qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
    }
  }

  for (int row = 0; row < results_per_simdgroup; row++) {
    result[row] = simd_sum(result[row]);
    if (simd_lid == 0) {
      y[row] = static_cast<T>(result[row]);
    }
  }
}

template <typename T, int group_size, int bits>
METAL_FUNC void qmv_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  constexpr int num_simdgroups = 4;
  constexpr int results_per_simdgroup = 4;
  constexpr int packs_per_thread = 1;
  constexpr int pack_factor = get_pack_factor<bits, 32>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits, 32>();

  constexpr int values_per_thread = pack_factor * packs_per_thread;
  constexpr int block_size = values_per_thread * SIMD_SIZE;
  constexpr int scale_step_per_thread = group_size / values_per_thread;

  const device uint8_t* ws = (const device uint8_t*)w;

  typedef float U;

  thread U x_thread[values_per_thread];
  thread U result[results_per_simdgroup] = {0};

  // Adjust positions
  const int in_vec_size_w = in_vec_size * bytes_per_pack / pack_factor;
  const int in_vec_size_g = in_vec_size / group_size;
  const int out_row = tid.y * (num_simdgroups * results_per_simdgroup) +
      simd_gid * results_per_simdgroup;
  const int used_out_row = min(out_vec_size - results_per_simdgroup, out_row);

  if (out_row >= out_vec_size) {
    return;
  }

  // In this case we need to properly guard all our reads because there isn't
  // even 1 tile in the matrix
  if (out_vec_size < (num_simdgroups * results_per_simdgroup)) {
    ws +=
        out_row * in_vec_size_w + simd_lid * packs_per_thread * bytes_per_pack;
    scales += out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
    biases += out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
    x += tid.x * in_vec_size + simd_lid * values_per_thread;
    y += tid.x * out_vec_size + out_row;

    int k = 0;
    for (; k < in_vec_size - block_size; k += block_size) {
      U sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);

      for (int row = 0;
           row < results_per_simdgroup && out_row + row < out_vec_size;
           row++) {
        auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
        const device T* sl = scales + row * in_vec_size_g;
        const device T* bl = biases + row * in_vec_size_g;

        U s = sl[0];
        U b = bl[0];
        result[row] +=
            qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
      }

      ws += block_size * bytes_per_pack / pack_factor;
      scales += block_size / group_size;
      biases += block_size / group_size;
      x += block_size;
    }
    const int remaining = clamp(
        static_cast<int>(in_vec_size - k - simd_lid * values_per_thread),
        0,
        values_per_thread);
    if (remaining > 0) {
      U sum = load_vector_safe<T, U, values_per_thread, bits>(
          x, x_thread, remaining);

      for (int row = 0;
        en file) to every request, so a stale token 401s even
    the public model listing (#2276, #2310). Listing needs no auth, so retry
    once with token=False and report the rejected token to the caller.
    """
    try:
        return list(api.list_models(**kwargs)), False
    except HfHubHTTPError as e:
        if e.response is None or e.response.status_code != 401:
            raise
        logger.warning(
            "HF model listing rejected the stored token (401): %s. "
            "Retrying anonymously.",
            e,
        )
        return list(api.list_models(token=False, **kwargs)), True


class DownloadStatus(str, enum.Enum):
    """Status of a download task."""

    PENDING = "pending"
    DOWNLOADING = "downloading"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


@dataclass
class DownloadTask:
    """Represents a single model download task."""

    task_id: str
    repo_id: str
    status: DownloadStatus = DownloadStatus.PENDING
    progress: float = 0.0
    total_size: int = 0
    downloaded_size: int = 0
    error: str = ""
    created_at: float = field(default_factory=time.time)
    started_at: float = 0.0
    completed_at: float = 0.0
    retry_count: int = 0

    def to_dict(self) -> dict:
        """Serialize task to a JSON-compatible dict."""
        return {
            "task_id": self.task_id,
            "repo_id": self.repo_id,
            "status": self.status.value,
            "progress": round(self.progress, 1),
            "total_size": self.total_size,
            "downloaded_size": self.downloaded_size,
            "error": self.error,
            "created_at": self.created_at,
            "started_at": self.started_at,
            "completed_at": self.completed_at,
            "retry_count": self.retry_count,
        }


_DTYPE_BYTES = {
    "F64": 8, "F32": 4, "F16": 2, "BF16": 2,
    "I64": 8, "I32": 4, "I16": 2, "I8": 1,
    "U64": 8, "U32": 4, "U16": 2, "U8": 1,
    "BOOL": 1,
}

# Minimum downloads to be included in recommendations.
_MIN_DOWNLOADS = 100


def _calc_safetensors_disk_size(safetensors: dict) -> int:
    """Calculate actual disk size in bytes from safetensors parameters.

    safetensors.total is the parameter count, not bytes.
    We need to multiply each dtype's parameter count by its byte width.
    """
    params = safetensors.get("parameters", {})
    if not params:
        return 0
    return sum(count * _DTYPE_BYTES.get(dtype, 1) for dtype, count in params.items())


def _format_model_size(size_bytes: int) -> str:
    """Format model size in bytes to a human-readable string."""
    if size_bytes < 1024**2:
        return f"{size_bytes / 1024:.1f} KB"
    elif size_bytes < 1024**3:
        return f"{size_bytes / 1024**2:.1f} MB"
    else:
        return f"{size_bytes / 1024**3:.1f} GB"


def _format_param_count(total_params: int) -> str:
    """Format parameter count to a human-readable string (e.g., 7.0B, 13.0B)."""
    if total_params >= 1e12:
        return f"{total_params / 1e12:.1f}T"
    if total_params >= 1e9:
        return f"{total_params / 1e9:.1f}B"
    if total_params >= 1e6:
        return f"{total_params / 1e6:.1f}M"
    return str(total_params)


def _get_param_count(safetensors: dict) -> int:
    """Get total parameter count from safetensors metadata."""
    params = safetensors.get("parameters", {})
    if not params:
        return 0
    return sum(params.values())


# HF API sort field mapping for search.
_SORT_MAP = {
    "trending": "trendingScore",
    "downloads": "downloads",
    "created": "createdAt",
    "updated": "lastModified",
    "most_params": "downloads",  # fetch by downloads, re-sort in Python
    "least_params": "downloads",  # fetch by downloads, re-sort in Python
    "largest": "downloads",  # fetch by downloads, re-sort by size in Python
    "smallest": "downloads",  # fetch by downloads, re-sort by size in Python
}


class HFDownloader:
    """Manages HuggingFace model downloads with progress tracking.

    Uses huggingface_hub.snapshot_download() for actual downloads and polls
    the targeodel,
                label: String(localized: "settings.profiles.model.label",
                              defaultValue: "Model Profiles · \(vm.model?.id ?? vm.modelID)",
                              comment: "Section label for the per-model profile chip group; placeholder is the model id"),
                names: vm.profiles
                    .filter { $0.sourceTemplate == nil }
                    .map(\.name),
                activeName: vm.activeProfileState.activeName(in: .model),
                basedOnName: vm.activeProfileState.basedOnName(in: .model),
                previewName: preview?.scope == .model ? preview?.name : nil,
                canSaveCurrent: vm.profileDirty,
                onSelect: { previewChip(scope: .model, name: $0) },
                onSaveCurrent: { openSaveAs(scope: .model) },
                onRename: { original, renamed in
                    Task { await vm.renameModelProfile(from: original, to: renamed, client: client) }
                }
            )

            detailCard

            SectionHeader(
                String(localized: "settings.profiles.server_defaults.title",
                       defaultValue: "Server Defaults",
                       comment: "Section header above the read-only Server Defaults card"),
                subtitle: String(localized: "settings.profiles.server_defaults.subtitle",
                                 defaultValue: "Used when no profile is set, or when a profile leaves a field empty",
                                 comment: "Subtitle explaining the role of the Server Defaults profile")
            ) {
                Button(String(localized: "settings.profiles.edit_on_server",
                              defaultValue: "Edit on Server →",
                              comment: "Plain link button that deep-links to the Server screen's Default Profile section")) {
                    onEditServer()
                }
                    .buttonStyle(.omlx(.plain, size: .small))
            }
            ProfileDetailCard(
                name: String(localized: "settings.profiles.server_default.name",
                             defaultValue: "Server Default Profile",
                             comment: "Display name of the synthesized 'Server Default' profile card"),
                scope: nil,
                settings: serverDefaultsAsDict(serverDefaults),
                isActive: false,
                isWorking: false,
                basedOn: nil,
                isWorkingBase: false,
                compact: true,
                hasWorking: false
            )
        }
    }

    @ViewBuilder
    private var detailCard: some View {
        if let preview, let tpl = lookupSettings(scope: preview.scope, name: preview.name) {
            ProfileDetailCard(
                name: preview.name,
                scope: preview.scope,
                settings: tpl,
                isActive: vm.activeProfileState.activeName(in: preview.scope) == preview.name,
                isWorking: false,
                basedOn: nil,
                isWorkingBase: vm.activeProfileState.basedOnName(in: preview.scope) == preview.name,
                compact: false,
                hasWorking: vm.profileDirty,
                onApply: {
                    Task {
                        if preview.scope == .preset,
                           let entry = presetStore.entries
                                .first(where: { $0.name == preview.name }) {
                            await vm.applyPreset(entry, client: client)
                        } else {
                            await vm.applyChip(
                                scope: preview.scope, name: preview.name, client: client
                            )
                        }
                        self.preview = nil
                    }
                },
                onUpdateFromWorking: vm.profileDirty && preview.scope != .preset
                    ? {
                        Task {
                            await vm.updateProfileWithWorking(
                            'GB').toUpperCase();
                if (unit === 'TB') bytes *= 1024 * 1024 * 1024 * 1024;
                else if (unit === 'GB') bytes *= 1024 * 1024 * 1024;
                else if (unit === 'MB') bytes *= 1024 * 1024;

                const percent = Math.round((bytes / totalBytes) * 100);
                return Math.min(50, Math.max(0, percent));
            },

            // Update hot cache setting from slider
            updateHotCacheFromSlider() {
                if (this.hotCachePercent === 0) {
                    this.globalSettings.cache.hot_cache_max_size = '0';
                } else {
                    const totalBytes = this.globalSettings.system?.total_memory_bytes || 0;
                    const bytes = Math.floor((this.hotCachePercent / 100) * totalBytes);
                    const gb = Math.floor(bytes / (1024 * 1024 * 1024));
                    this.globalSettings.cache.hot_cache_max_size = gb > 0 ? `${gb}GB` : '0';
                }
            },

            // Get formatted hot cache size for display
            getHotCacheDisplay() {
                if (this.hotCachePercent === 0) return '0GB';
                const totalBytes = this.globalSettings.system?.total_memory_bytes || 0;
                const bytes = Math.floor((this.hotCachePercent / 100) * totalBytes);
                const gb = Math.floor(bytes / (1024 * 1024 * 1024));
                return `${gb}GB`;
            },

            // Filter + sort models
            get sortedModels() {
                return [...this.filterModelsByName(this.models, this.modelSearch)].sort((a, b) => {
                    // Favorites always sort first, regardless of the active column.
                    const favDiff = (b.is_favorite ? 1 : 0) - (a.is_favorite ? 1 : 0);
                    if (favDiff !== 0) return favDiff;

                    let aVal, bVal;

                    switch (this.sortBy) {
                        case 'id':
                            aVal = (a.display_name || a.id || '').toLowerCase();
                            bVal = (b.display_name || b.id || '').toLowerCase();
                            break;
                        case 'type':
                            aVal = (a.model_type || 'llm').toLowerCase();
                            bVal = (b.model_type || 'llm').toLowerCase();
                            break;
                        case 'size':
                            aVal = a.estimated_size || 0;
                            bVal = b.estimated_size || 0;
                            break;
                        case 'loaded':
                            aVal = a.loaded ? 1 : 0;
                            bVal = b.loaded ? 1 : 0;
                            break;
                        case 'pinned':
                            aVal = a.pinned ? 1 : 0;
                            bVal = b.pinned ? 1 : 0;
                            break;
                        case 'is_default':
                            aVal = a.is_default ? 1 : 0;
                            bVal = b.is_default ? 1 : 0;
                            break;
                        case 'is_hidden':
                            aVal = a.is_hidden ? 1 : 0;
                            bVal = b.is_hidden ? 1 : 0;
                            break;
                        default:
                            return 0;
                    }

                    if (aVal < bVal) return this.sortOrder === 'asc' ? -1 : 1;
                    if (aVal > bVal) return this.sortOrder === 'asc' ? 1 : -1;
                    return 0;
                });
            },

            toggleSort(column) {
                if (this.sortBy === column) {
                    this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
                } else {
                    this.sortBy = column;
                    this.sortOrder = 'asc';
                }
                this.persistSort('omlx_models_sort_by', this.sortBy, 'omlx_models_sort_order', this.sortOrder);
            },

            resetSort() {
                this.sortBy = MODELS_SOR   row < results_per_simdgroup && out_row + row < out_vec_size;
           row++) {
        auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
        const device T* sl = scales + row * in_vec_size_g;
        const device T* bl = biases + row * in_vec_size_g;

        U s = sl[0];
        U b = bl[0];
        result[row] += qdot_safe<U, values_per_thread, bits>(
            wl, x_thread, s, b, sum, remaining);
      }
    }

    for (int row = 0;
         row < results_per_simdgroup && out_row + row < out_vec_size;
         row++) {
      result[row] = simd_sum(result[row]);
      if (simd_lid == 0) {
        y[row] = static_cast<T>(result[row]);
      }
    }
  }

  // In this case the last tile is moved back to redo some output values
  else {
    ws += used_out_row * in_vec_size_w +
        simd_lid * packs_per_thread * bytes_per_pack;
    scales += used_out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
    biases += used_out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
    x += tid.x * in_vec_size + simd_lid * values_per_thread;
    y += tid.x * out_vec_size + used_out_row;

    int k = 0;
    for (; k < in_vec_size - block_size; k += block_size) {
      U sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);

      for (int row = 0; row < results_per_simdgroup; row++) {
        auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
        const device T* sl = scales + row * in_vec_size_g;
        const device T* bl = biases + row * in_vec_size_g;

        U s = sl[0];
        U b = bl[0];
        result[row] +=
            qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
      }

      ws += block_size * bytes_per_pack / pack_factor;
      scales += block_size / group_size;
      biases += block_size / group_size;
      x += block_size;
    }
    const int remaining = clamp(
        static_cast<int>(in_vec_size - k - simd_lid * values_per_thread),
        0,
        values_per_thread);
    if (remaining > 0) {
      U sum = load_vector_safe<T, U, values_per_thread, bits>(
          x, x_thread, remaining);

      for (int row = 0; row < results_per_simdgroup; row++) {
        auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
        const device T* sl = scales + row * in_vec_size_g;
        const device T* bl = biases + row * in_vec_size_g;

        U s = sl[0];
        U b = bl[0];
        result[row] += qdot_safe<U, values_per_thread, bits>(
            wl, x_thread, s, b, sum, remaining);
      }
    }
    for (int row = 0; row < results_per_simdgroup; row++) {
      result[row] = simd_sum(result[row]);
      if (simd_lid == 0) {
        y[row] = static_cast<T>(result[row]);
      }
    }
  }
}

// Affine analog of fp_qmv_wide. Weights carry a scale and bias per group, so
// each group is decoded in 8-value sub-chunks (scale * q + bias, registers
// bounded for any group_size) and reused across the vecs_per_tg vectors.
template <typename T, int group_size, int bits, int vecs_per_tg, int k_lanes, bool symmetric = false>
METAL_FUNC void qmv_wide_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    const constant int& M,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  constexpr int num_simdgroups = 4;
  constexpr int results_per_simdgroup = SIMD_SIZE / k_lanes;
  constexpr int sub = 8; // values per sub-chunk (== bits bytes, byte-aligned)

  typedef float U;

  const short k_lane = simd_lid % k_lanes;
  const short sg_row = simd_lid / k_lanes;

  const int out_row = tid.y * (results_per_simdgroup * num_simdgroups) +
      results_per_simdgroup * simd_gid + sg_row;
  const int vec0 = tid.x * vecs_per_tg;

  const int row = min(out_row, out_vec_size - 1);

  const int in_vec_size_w = in_vec_size * bits / 8; // bytes per weight row
  const int in_vec_size_g = in_vec_size / group_size;
  const directory size to estimate progress.

    Args:
        model_dir: Directory where downloaded models are stored.
        on_complete: Async callback invoked when a download completes successfully.
    """

    @staticmethod
    async def get_recommended_models(
        max_memory_bytes: int,
        limit: int = 60,
        result_limit: int = 50,
        mlx_only: bool = True,
    ) -> dict:
        """Fetch trending and popular models that fit in memory.

        Queries HuggingFace Hub for models, optionally restricted to
        mlx-community. Filtered by system memory capacity.

        Args:
            max_memory_bytes: Maximum model size in bytes (typically system memory).
            limit: Number of models to fetch per category from HF API.
            result_limit: Maximum number of models to return per category.
            mlx_only: If True, restrict to mlx-community author.

        Returns:
            Dict with 'trending' and 'popular' lists, plus 'hf_token_invalid'
            set when the stored HF token was rejected and the listing was
            fetched anonymously instead.
        """
        api, _endpoint = _get_hf_api()

        async def _fetch(sort: str) -> tuple[list[dict], bool]:
            kwargs = {
                "sort": sort,
                "limit": limit,
                "expand": ["safetensors", "downloads", "likes", "trendingScore"],
            }
            if mlx_only:
                kwargs["author"] = "mlx-community"
            # list_models returns a lazy generator; drain it inside the worker
            # thread so the paginated HTTP calls never block the event loop.
            models, token_rejected = await asyncio.wait_for(
                asyncio.to_thread(_list_models_stale_token_fallback, api, kwargs),
                timeout=_HF_API_TIMEOUT,
            )
            results = []
            for m in models:
                if not m.safetensors or not m.safetensors.get("parameters"):
                    continue
                downloads = m.downloads or 0
                if downloads < _MIN_DOWNLOADS:
                    continue
                size = _calc_safetensors_disk_size(m.safetensors)
                if size <= 0 or size > max_memory_bytes:
                    continue
                params = _get_param_count(m.safetensors)
                results.append(
                    {
                        "repo_id": m.id,
                        "name": m.id.split("/")[-1],
                        "downloads": downloads,
                        "likes": m.likes or 0,
                        "trending_score": m.trending_score or 0,
                        "size": size,
                        "size_formatted": _format_model_size(size),
                        "params": params if params > 0 else None,
                        "params_formatted": (
                            _format_param_count(params) if params > 0 else None
                        ),
                    }
                )
            return results, token_rejected

        (trending, trending_rejected), (popular, popular_rejected) = (
            await asyncio.gather(
                _fetch("trendingScore"),
                _fetch("downloads"),
            )
        )

        return {
            "trending": trending[:result_limit],
            "popular": popular[:result_limit],
            "hf_token_invalid": trending_rejected or popular_rejected,
        }

    @staticmethod
    async def search_models(
        query: str,
        sort: str = "trending",
        limit: int = 100,
        mlx_only: bool = True,
        # Filtering options
        min_params: Optional[int] = None,
        max_params: Optional[int] = None,
        min_size: Optional[int] = None,
        max_size: Optional[int] = None,
        # Sorting options
        sort_by_size: bool = False,
        sort_ascending: bool = False,
    ) -> dict:
        """Search HuggingFace models by query string with filtering and sorting.

        When mlx_only is True, results are restricted to the MLX library
        (same as https://h     scope: preview.scope, name: preview.name, client: client
                            )
                            self.preview = nil
                        }
                    }
                    : nil,
                onDelete: preview.scope == .preset ? nil : {
                    Task {
                        await deleteChip(scope: preview.scope, name: preview.name)
                        self.preview = nil
                    }
                },
                onClosePreview: { self.preview = nil },
                exposeAsModel: modelProfile(named: preview.name)?.exposeAsModel ?? false,
                exposedModelId: modelProfile(named: preview.name)?.modelId,
                hasEngineFields: modelProfile(named: preview.name)?.hasEngineFields ?? false,
                onToggleExpose: preview.scope == .model
                    ? { exposed in
                        Task {
                            await vm.setExposeAsModel(
                                name: preview.name, exposed: exposed, client: client
                            )
                        }
                    }
                    : nil
            )
        } else {
            // No preview → show the active state's detail.
            switch vm.activeProfileState {
            case .working(let basedOn):
                ProfileDetailCard(
                    name: String(localized: "settings.profiles.working.name",
                                 defaultValue: "Working profile",
                                 comment: "Display name for the in-progress (unsaved) working profile detail card"),
                    scope: basedOn?.scope,
                    settings: vm.currentSettingsDict(),
                    isActive: true,
                    isWorking: true,
                    basedOn: basedOn,
                    isWorkingBase: false,
                    compact: false,
                    hasWorking: true
                )
            case .named(let scope, let name):
                let settings = lookupSettings(scope: scope, name: name) ?? [:]
                ProfileDetailCard(
                    name: name,
                    scope: scope,
                    settings: settings,
                    isActive: true,
                    isWorking: false,
                    basedOn: nil,
                    isWorkingBase: false,
                    compact: false,
                    hasWorking: false,
                    exposeAsModel: modelProfile(named: name)?.exposeAsModel ?? false,
                    exposedModelId: modelProfile(named: name)?.modelId,
                    hasEngineFields: modelProfile(named: name)?.hasEngineFields ?? false,
                    onToggleExpose: scope == .model
                        ? { exposed in
                            Task {
                                await vm.setExposeAsModel(
                                    name: name, exposed: exposed, client: client
                                )
                            }
                        }
                        : nil
                )
            case .defaults:
                ProfileDetailCard(
                    name: String(localized: "settings.profiles.no_profile.name",
                                 defaultValue: "No profile",
                                 comment: "Display name shown in the profile detail card when no profile is active"),
                    scope: nil,
                    settings: serverDefaultsAsDict(serverDefaults),
                    isActive: true,
                    isWorking: false,
                    basedOn: nil,
                    isWorkingBase: false,
                    compact: false,
                    hasWorking: false
                )
            }
        }
    }

    /// Per-model profile DTO lookup — source of the expose-as-model state
    /// and the derived model ID shown on the detail card.
    private func modelProfile(named name: String) -> ProfileDTO? {
        vm.profiles.first { $0.name == name }
    }

    private func previewChip(scope: ProT_DEFAULT.by;
                this.sortOrder = MODELS_SORT_DEFAULT.order;
                try {
                    localStorage.removeItem('omlx_models_sort_by');
                    localStorage.removeItem('omlx_models_sort_order');
                } catch (e) { /* storage disabled */ }
            },

            get isModelsSortDefault() {
                return this.sortBy === MODELS_SORT_DEFAULT.by
                    && this.sortOrder === MODELS_SORT_DEFAULT.order;
            },

            // ---- Manager (Browse Models > Local) filter + sort ----

            // Cross-reference the richer /api/models entry (has model_type,
            // settings) for a manager row keyed by its model name.
            managerModelInfo(name) {
                return this.models.find(m => m.id === name);
            },

            filterModelsByName(list, query) {
                const q = (query || '').trim().toLowerCase();
                if (!q) return list;
                return list.filter(m => {
                    const id = (m.id || m.name || '').toLowerCase();
                    const display = (m.display_name || '').toLowerCase();
                    const alias = (
                        (m.settings && m.settings.model_alias)
                        || (this.managerModelInfo(m.name) && this.managerModelInfo(m.name).settings
                            && this.managerModelInfo(m.name).settings.model_alias)
                        || ''
                    ).toLowerCase();
                    return id.includes(q) || display.includes(q) || alias.includes(q);
                });
            },

            get sortedManagerModels() {
                const list = this.filterModelsByName(this.hfModels, this.managerSearch);
                return [...list].sort((a, b) => {
                    // Favorites always sort first, regardless of the active column.
                    const aFav = this.managerModelInfo(a.name)?.is_favorite ? 1 : 0;
                    const bFav = this.managerModelInfo(b.name)?.is_favorite ? 1 : 0;
                    if (aFav !== bFav) return bFav - aFav;

                    let aVal, bVal;
                    switch (this.managerSortBy) {
                        case 'name':
                            aVal = (a.display_name || a.name || '').toLowerCase();
                            bVal = (b.display_name || b.name || '').toLowerCase();
                            break;
                        case 'type':
                            aVal = (this.managerModelInfo(a.name)?.model_type || 'llm').toLowerCase();
                            bVal = (this.managerModelInfo(b.name)?.model_type || 'llm').toLowerCase();
                            break;
                        case 'size':
                            aVal = a.size || 0;
                            bVal = b.size || 0;
                            break;
                        default:
                            return 0;
                    }
                    if (aVal < bVal) return this.managerSortOrder === 'asc' ? -1 : 1;
                    if (aVal > bVal) return this.managerSortOrder === 'asc' ? 1 : -1;
                    return 0;
                });
            },

            toggleManagerSort(column) {
                if (this.managerSortBy === column) {
                    this.managerSortOrder = this.managerSortOrder === 'asc' ? 'desc' : 'asc';
                } else {
                    this.managerSortBy = column;
                    this.managerSortOrder = 'asc';
                }
                this.persistSort('omlx_manager_sort_by', this.managerSortBy, 'omlx_manager_sort_order', this.managerSortOrder);
            },

            resetManagerSort() {
                this.managerSortBy = MANAGER_SORT_DEFAULT.by;
                this.managerSortOrder = MANAGER_SORT_DEFAULT.order;
                try {
                    localStorage.removeItem('omlx_manager_sort_by');
                    localStorage.removeItem('omlx_manager_sort_order');
                } catch (e) { /* storage disabled */ }
            },

    t device uint8_t* wrow = (const device uint8_t*)w + row * in_vec_size_w;
  const device T* srow = scales + row * in_vec_size_g;
  // brow not declared when symmetric=true; DCE'd by compiler when false.
  const device T* brow = symmetric ? nullptr : biases + row * in_vec_size_g;

  const device T* xv[vecs_per_tg];
  for (int v = 0; v < vecs_per_tg; v++) {
    xv[v] = x + min(vec0 + v, M - 1) * in_vec_size;
  }

  U result[vecs_per_tg] = {0};

  // Each lane reduces a strided subset of the row's groups: decode the group in
  // 8-value sub-chunks and reuse each chunk across the streamed vectors.
  for (int g = k_lane; g < in_vec_size_g; g += k_lanes) {
    U scale = srow[g];
    // I-B: symmetric layers have bias = -scale * ratio; no DRAM load.
    // bits=1: ratio=0.5 (bias=-scale/2), bits=2: ratio=1.0 (bias=-scale)
    U bias;
    if constexpr (symmetric) {
      bias = -scale * U(bits == 1 ? 0.5f : 1.0f);
    } else {
      bias = brow[g];
    }
    // Precompute once per group; compiler dead-code-eliminates unused vars.
    U spb  = scale + bias;          // bits==1: lut[1]; bits==2: lut[1]
    U lut2 = fma(U(2), scale, bias); // bits==2: lut[2]; eliminated otherwise
    U lut3 = fma(U(3), scale, bias); // bits==2: lut[3]; eliminated otherwise
#pragma unroll
    for (int sc = 0; sc < group_size / sub; sc++) {
      const int k0 = g * group_size + sc * sub;
      const device uint8_t* wc = wrow + k0 * bits / 8;
      U w_dq[sub];
      if constexpr (bits == 1) {
        // sub=8 elements packed in 1 byte; spb hoisted to group scope.
        uint8_t wb = wc[0];
        w_dq[0] = select(bias, spb, bool(wb & 0x01));
        w_dq[1] = select(bias, spb, bool(wb & 0x02));
        w_dq[2] = select(bias, spb, bool(wb & 0x04));
        w_dq[3] = select(bias, spb, bool(wb & 0x08));
        w_dq[4] = select(bias, spb, bool(wb & 0x10));
        w_dq[5] = select(bias, spb, bool(wb & 0x20));
        w_dq[6] = select(bias, spb, bool(wb & 0x40));
        w_dq[7] = select(bias, spb, bool(wb & 0x80));
      } else if constexpr (bits == 2) {
        // sub=8 values from 2 bytes. Hoisted d0..d3 (computed once per group)
        // replace per-element scale*q+bias with 2 select() ops per value.
        // select() → single hardware instruction; no dynamic array index (avoids
        // register spilling on Apple GPU).
        auto mux2 = [&](uint8_t q) -> U {
          return select(select(bias, spb, bool(q & 1)),
                        select(lut2, lut3, bool(q & 1)), bool(q & 2));
        };
        uint8_t wb0 = wc[0], wb1 = wc[1];
        w_dq[0] = mux2(wb0 & 0x03);
        w_dq[1] = mux2((wb0 >> 2) & 0x03);
        w_dq[2] = mux2((wb0 >> 4) & 0x03);
        w_dq[3] = mux2((wb0 >> 6) & 0x03);
        w_dq[4] = mux2(wb1 & 0x03);
        w_dq[5] = mux2((wb1 >> 2) & 0x03);
        w_dq[6] = mux2((wb1 >> 4) & 0x03);
        w_dq[7] = mux2((wb1 >> 6) & 0x03);
      } else {
        dequantize<U, sub, bits>(wc, scale, bias, w_dq);
      }
#pragma unroll
      for (int v = 0; v < vecs_per_tg; v++) {
        const device T* xc = xv[v] + k0;
        U acc = 0;
#pragma unroll
        for (int i = 0; i < sub; i++) {
          acc += static_cast<U>(xc[i]) * w_dq[i];
        }
        result[v] += acc;
      }
    }
  }

  // Reduce each vector's partial over its k_lanes with a shuffle ladder:
  // simd_sum would mix the results_per_simdgroup rows a simdgroup spans.
  for (int v = 0; v < vecs_per_tg; v++) {
    if constexpr (k_lanes >= 32) {
      result[v] += simd_shuffle_down(result[v], 16);
    }
    if constexpr (k_lanes >= 16) {
      result[v] += simd_shuffle_down(result[v], 8);
    }
    if constexpr (k_lanes >= 8) {
      result[v] += simd_shuffle_down(result[v], 4);
    }
    if constexpr (k_lanes >= 4) {
      result[v] += simd_shuffle_down(result[v], 2);
    }
    if constexpr (k_lanes >= 2) {
      result[v] += simd_shuffle_down(result[v], 1);
    }
  }

  if (k_lane == 0 && out_row < out_vec_size) {
    for (int v = 0; v < vecs_per_tg; v++) {
      if (vec0 + v < M) {
        y[(vec0 + v) * out_vec_size + out_row] = static_cast<T>(resuuggingface.co/models?library=mlx).

        Args:
            query: Search query string.
            sort: Sort order (trending/downloads/created/updated/most_params/least_params/largest/smallest).
            limit: Maximum number of results to return.
            mlx_only: If True, restrict to MLX library models only.
            min_params: Minimum parameter count filter.
            max_params: Maximum parameter count filter.
            min_size: Minimum model size in bytes filter.
            max_size: Maximum model size in bytes filter.
            sort_by_size: Sort results by size instead of default sort.
            sort_ascending: Sort in ascending order (for size/params sorting).

        Returns:
            Dict with 'models' list and 'total' count, plus 'hf_token_invalid'
            set when the stored HF token was rejected and the listing was
            fetched anonymously instead.
        """
        api, _endpoint = _get_hf_api()

        # Determine base sort - for Python-side sorting, we fetch by downloads
        # which tends to return more results, then sort in Python
        if sort in ("most_params", "least_params", "largest", "smallest"):
            base_sort = "downloads"
        else:
            base_sort = _SORT_MAP.get(sort, "trendingScore")

        kwargs = {
            "search": query,
            "sort": base_sort,
            "limit": limit,
            "expand": ["safetensors", "downloads", "likes", "trendingScore"],
        }
        if mlx_only:
            kwargs["filter"] = "mlx"

        # list_models returns a lazy generator; drain it inside the worker
        # thread so the paginated HTTP calls never block the event loop.
        models, token_rejected = await asyncio.wait_for(
            asyncio.to_thread(_list_models_stale_token_fallback, api, kwargs),
            timeout=_HF_API_TIMEOUT,
        )

        results = []
        for m in models:
            params = None
            params_formatted = None
            size = 0

            if m.safetensors and m.safetensors.get("parameters"):
                params = _get_param_count(m.safetensors)
                params_formatted = _format_param_count(params) if params > 0 else None
                size = _calc_safetensors_disk_size(m.safetensors)
                if params and params <= 0:
                    params = None

            # Apply filters
            if min_params is not None and (params is None or params < min_params):
                continue
            if max_params is not None and (params is None or params > max_params):
                continue
            if min_size is not None and size < min_size:
                continue
            if max_size is not None and size > max_size:
                continue

            results.append(
                {
                    "repo_id": m.id,
                    "name": m.id,
                    "downloads": m.downloads or 0,
                    "likes": m.likes or 0,
                    "trending_score": m.trending_score or 0,
                    "size": size,
                    "size_formatted": _format_model_size(size) if size > 0 else "",
                    "params": params,
                    "params_formatted": params_formatted,
                }
            )

        # Apply Python-side sorting
        if sort == "most_params":
            results.sort(key=lambda x: x["params"] or 0, reverse=True)
        elif sort == "least_params":
            results.sort(key=lambda x: x["params"] or 0)
        elif sort in ("largest", "smallest") or sort_by_size:
            # Sort by size, putting unknown-size entries at the end
            results.sort(
                key=lambda x: x["size"] if x["size"] > 0 else -1,
                reverse=(sort == "largest" or (sort_by_size and not sort_ascending)),
            )
        # Otherwise, keep original HF API ordering (trending, downloads, created, updated)

        return {
            "models": results[:limit],
            "total": len(results),
            "hf_token_invalid": token_rejected,
        }

 fileScope, name: String) {
        // Toggle off when re-clicking the same chip.
        if preview?.scope == scope && preview?.name == name {
            preview = nil
        } else {
            preview = .init(scope: scope, name: name)
        }
    }

    private func openSaveAs(scope: ProfileScope) {
        saveAsScope = scope
        saveAsName = vm.suggestSaveAsName()
        saveAsOpen = true
    }

    private func deleteChip(scope: ProfileScope, name: String) async {
        do {
            switch scope {
            case .global:
                _ = try await client.deleteProfileTemplate(name: name)
            case .model:
                _ = try await client.deleteModelProfile(id: vm.modelID, name: name)
            case .preset:
                return
            }
            await vm.load(modelID: vm.modelID, client: client)
        } catch {
            // Surfaces via the screen's lastError banner — set on the VM.
            await MainActor.run { vm.lastError = error.omlxDescription }
        }
    }

    private func lookupSettings(scope: ProfileScope, name: String) -> [String: AnyCodable]? {
        switch scope {
        case .preset:
            return presetStore.entries.first(where: { $0.name == name })?.settings
        case .global:
            return vm.templates.first(where: { $0.name == name })?.settings
        case .model:
            return vm.profiles.first(where: { $0.name == name })?.settings
        }
    }

}

/// Translate the server's typed SamplingDTO into the loose dict the
/// ProfileDetailCard renders against. Keys match `ProfileSettingsKey`.
private func serverDefaultsAsDict(_ s: GlobalSettingsDTO.SamplingDTO?) -> [String: AnyCodable] {
    guard let s else { return [:] }
    return [
        ProfileSettingsKey.maxContextWindow:  AnyCodable(s.maxContextWindow),
        ProfileSettingsKey.maxTokens:         AnyCodable(s.maxTokens),
        ProfileSettingsKey.temperature:       AnyCodable(s.temperature),
        ProfileSettingsKey.topP:              AnyCodable(s.topP),
        ProfileSettingsKey.topK:              AnyCodable(s.topK),
        ProfileSettingsKey.repetitionPenalty: AnyCodable(s.repetitionPenalty),
    ]
}

private extension ActiveProfileState {
    /// Name of the active profile if it lives in the given scope, else nil.
    func activeName(in scope: ProfileScope) -> String? {
        if case .named(let s, let n) = self, s == scope { return n }
        return nil
    }

    /// Name of the "based on" reference if it lives in the given scope.
    func basedOnName(in scope: ProfileScope) -> String? {
        if case .working(let basedOn) = self, let basedOn, basedOn.scope == scope {
            return basedOn.name
        }
        return nil
    }
}

// ProfileChips / ChipView / FlowHStack / FlowLayout were the v1 layout
// of the Profiles tab. Replaced by ProfileGroup + ProfileViews.FlowLayout
// when the working-profile redesign landed.

// MARK: - Basic tab

private struct BasicTab: View {
    @Bindable var vm: ModelSettingsScreenVM
    let client: OMLXClient

    var body: some View {
        BasicEditBanner(vm: vm, client: client)
        SectionHeader(String(localized: "settings.basic.section",
                             defaultValue: "Basic Settings",
                             comment: "Section header above the Basic tab fields"))

        // Per-model fields (alias / modelType / TTL) auto-save on commit.
        // Profile-eligible fields (sampling, penalties) write to the
        // working profile instead — surfaced via the banner above.
        ListGroup {
            Row(label: String(localized: "settings.basic.alias.label",
                              defaultValue: "Model Alias",
                              comment: "Row label for the model alias field"),
                sublabel: String(localized: "settings.basic.alias.sub",
                                 defaultValue: "Falls back to the model id",
                                 comment: "Sublabel for the model alias field")) {
                TextInput(text: $vm.alias, placeholder: vm.m        get isManagerSortDefault() {
                return this.managerSortBy === MANAGER_SORT_DEFAULT.by
                    && this.managerSortOrder === MANAGER_SORT_DEFAULT.order;
            },

            persistSort(byKey, byVal, orderKey, orderVal) {
                try {
                    localStorage.setItem(byKey, byVal);
                    localStorage.setItem(orderKey, orderVal);
                } catch (e) { /* storage disabled */ }
            },

            // Deeplink from a manager row to that model's settings card (modal).
            openModelSettingsFromManager(name) {
                const model = this.managerModelInfo(name);
                if (model) this.openModelSettings(model);
            },

            // Theme select
            setTheme(theme) {
                this.theme = theme;
                localStorage.setItem('omlx-chat-theme', this.theme);
                this.applyTheme();
            },

            applyTheme() {
                // Clean up existing listener
                if (this.systemThemeListener) {
                    window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', this.systemThemeListener);
                    this.systemThemeListener = null;
                }

                if (this.theme === 'auto') {
                    // Detect system theme
                    const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
                    this.activeTheme = prefersDark ? 'dark' : 'light';
                    document.documentElement.setAttribute('data-theme', this.activeTheme);

                    // Add listener for system theme changes
                    this.systemThemeListener = (e) => {
                        this.activeTheme = e.matches ? 'dark' : 'light';
                        document.documentElement.setAttribute('data-theme', this.activeTheme);
                    };
                    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', this.systemThemeListener);
                } else {
                    // Use explicit theme
                    this.activeTheme = this.theme;
                    document.documentElement.setAttribute('data-theme', this.activeTheme);
                }
            },

            // =================================================================
            // HuggingFace Mirror Settings
            // =================================================================

            openHfMirrorModal() {
                this.hfMirrorEndpoint = this.globalSettings.huggingface.endpoint || '';
                this.showHfMirrorModal = true;
            },

            async saveHfMirrorEndpoint() {
                this.hfMirrorSaving = true;
                try {
                    const response = await fetch('/admin/api/global-settings', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ hf_endpoint: this.hfMirrorEndpoint }),
                    });
                    if (response.ok) {
                        this.globalSettings.huggingface.endpoint = this.hfMirrorEndpoint;
                        this.showHfMirrorModal = false;
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json();
                        alert(Array.isArray(data.detail) ? data.detail.map(e => (e && typeof e === 'object') ? (e.msg || JSON.stringify(e)) : String(e)).join(', ') : (data.detail || 'Failed to save'));
                    }
                } catch (err) {
                    console.error('Failed to save HF mirror endpoint:', err);
                } finally {
                    this.hfMirrorSaving = false;
                }
            },

            // =================================================================
            // HuggingFace Downloader Functions
            // ====================lt[v]);
      }
    }
  }
}

// ---------------------------------------------------------------------------
// Realization 2.3 (I-K): Granlund-Montgomery magic divmod-3, exact for v ∈ [0,255].
// ⌊v/3⌋ = (v·171) >> 9  — no integer divide instruction, pure multiply + shift.
// Then v mod 3 = v − 3q = v − (q<<1) − q.
METAL_FUNC uint t5_div3(uint v)  { return (v * 171u) >> 9u; }

// Parallel trit extraction helpers (I-L): all operate on the ORIGINAL byte v,
// so ALL four calls can be issued simultaneously with no serial data dependency.
// Exact for v ∈ [0, 242] (max valid t5 byte = 3^5 − 1 = 242).
METAL_FUNC uint t5_div9(uint v)  { return (v * 228u) >> 11u; }  // ⌊v/9⌋
METAL_FUNC uint t5_div27(uint v) { return (v * 76u)  >> 11u; }  // ⌊v/27⌋
// ⌊v/81⌋ ∈ {0,1,2}: two independent comparisons, no multiply needed.
// Precondition: v ∈ [0, 242] (max valid t5 byte = 3^5 − 1 = 242).
// v=243 cannot appear in a validly-encoded t5 stream, so v/81 ≤ 2 always.
METAL_FUNC uint t5_div81(uint v) { return uint(v >= 81u) + uint(v >= 162u); }

// T5_TO_B4: radix-conversion LUT — maps each t5 byte (0..242) to its 5 trits
// repacked as 2-bit fields in a uint.  Field k occupies bits [2k+1 : 2k]:
//   bits[1:0] = t0,  bits[3:2] = t1,  bits[5:4] = t2,
//   bits[7:6] = t3,  bits[9:8] = t4,  tₖ ∈ {0,1,2}.
//
// This enables the same pre-scaling trick as 2-bit affine (I-L):
//   x_pre[k] = x[k] × 4^{−k}
//   x_pre[k] × (T5_TO_B4[v] & (3 << 2k))  =  x[k] × tₖ   (no division)
// The −1 offset is absorbed via x_sum: result = s × (Σ x[k]tₖ − Σ x[k]).
// 256 entries × 4 bytes = 1 KB; permanently L1-resident during GEMV.
constant constexpr uint T5_TO_B4[256] = {
    0x000, 0x001, 0x002, 0x004, 0x005, 0x006, 0x008, 0x009,
    0x00A, 0x010, 0x011, 0x012, 0x014, 0x015, 0x016, 0x018,
    0x019, 0x01A, 0x020, 0x021, 0x022, 0x024, 0x025, 0x026,
    0x028, 0x029, 0x02A, 0x040, 0x041, 0x042, 0x044, 0x045,
    0x046, 0x048, 0x049, 0x04A, 0x050, 0x051, 0x052, 0x054,
    0x055, 0x056, 0x058, 0x059, 0x05A, 0x060, 0x061, 0x062,
    0x064, 0x065, 0x066, 0x068, 0x069, 0x06A, 0x080, 0x081,
    0x082, 0x084, 0x085, 0x086, 0x088, 0x089, 0x08A, 0x090,
    0x091, 0x092, 0x094, 0x095, 0x096, 0x098, 0x099, 0x09A,
    0x0A0, 0x0A1, 0x0A2, 0x0A4, 0x0A5, 0x0A6, 0x0A8, 0x0A9,
    0x0AA, 0x100, 0x101, 0x102, 0x104, 0x105, 0x106, 0x108,
    0x109, 0x10A, 0x110, 0x111, 0x112, 0x114, 0x115, 0x116,
    0x118, 0x119, 0x11A, 0x120, 0x121, 0x122, 0x124, 0x125,
    0x126, 0x128, 0x129, 0x12A, 0x140, 0x141, 0x142, 0x144,
    0x145, 0x146, 0x148, 0x149, 0x14A, 0x150, 0x151, 0x152,
    0x154, 0x155, 0x156, 0x158, 0x159, 0x15A, 0x160, 0x161,
    0x162, 0x164, 0x165, 0x166, 0x168, 0x169, 0x16A, 0x180,
    0x181, 0x182, 0x184, 0x185, 0x186, 0x188, 0x189, 0x18A,
    0x190, 0x191, 0x192, 0x194, 0x195, 0x196, 0x198, 0x199,
    0x19A, 0x1A0, 0x1A1, 0x1A2, 0x1A4, 0x1A5, 0x1A6, 0x1A8,
    0x1A9, 0x1AA, 0x200, 0x201, 0x202, 0x204, 0x205, 0x206,
    0x208, 0x209, 0x20A, 0x210, 0x211, 0x212, 0x214, 0x215,
    0x216, 0x218, 0x219, 0x21A, 0x220, 0x221, 0x222, 0x224,
    0x225, 0x226, 0x228, 0x229, 0x22A, 0x240, 0x241, 0x242,
    0x244, 0x245, 0x246, 0x248, 0x249, 0x24A, 0x250, 0x251,
    0x252, 0x254, 0x255, 0x256, 0x258, 0x259, 0x25A, 0x260,
    0x261, 0x262, 0x264, 0x265, 0x266, 0x268, 0x269, 0x26A,
    0x280, 0x281, 0x282, 0x284, 0x285, 0x286, 0x288, 0x289,
    0x28A, 0x290, 0x291, 0x292, 0x294, 0x295, 0x296, 0x298,
    0x299, 0x29A, 0x2A0, 0x2A1, 0x2A2, 0x2A4, 0x2A5, 0x2A6,
    0x2A8, 0x2A9, 0x2AA, 0x000, 0x000, 0x000, 0x000, 0x000,
    0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
};
// ---------------------------------------------------------------------------
// qmv_fast_t5_impl — optimized (O1-O5)
//
// [O1] packed_uchar4 weight loads (alignment 1, 7 loads vs 26 per row-group)
// [O2] packed_half4 activation loads (2 loads vs 5 per 5-trit byte)
// [O3] 20-trit chunk structure (4 bytes x 5 trits, fully unrolled)
// [O4] USE_SIGMA: skip x_sum + pre-scale muls (sigma precomputed elsewhere)
// [O5] row clamping instead of duplicated boundary loop
// ---------------------------------------   @staticmethod
    async def get_model_info(repo_id: str) -> dict:
        """Fetch detailed model information from HuggingFace.

        Args:
            repo_id: HuggingFace repository ID (e.g., "mlx-community/Llama-3-8B-4bit").

        Returns:
            Dict with model details including description, files, tags, etc.
        """
        api, endpoint = _get_hf_api()
        info = await asyncio.wait_for(
            asyncio.to_thread(
                api.model_info,
                repo_id,
                files_metadata=True,
            ),
            timeout=_HF_API_TIMEOUT,
        )

        # Extract file list with sizes
        files = []
        if info.siblings:
            for s in info.siblings:
                files.append(
                    {
                        "name": s.rfilename,
                        "size": s.size or 0,
                        "size_formatted": (
                            _format_model_size(s.size) if s.size else ""
                        ),
                    }
                )

        # Detect LoRA/adapter repos (adapter_config.json is peft standard)
        is_adapter = any(f["name"] == "adapter_config.json" for f in files)

        # Extract params and size from safetensors
        params = None
        params_formatted = None
        size = 0
        safetensors = getattr(info, "safetensors", None)
        if safetensors:
            st_dict = dict(safetensors) if not isinstance(safetensors, dict) else safetensors
            if st_dict.get("parameters"):
                params = _get_param_count(st_dict)
                params_formatted = _format_param_count(params) if params > 0 else None
                size = _calc_safetensors_disk_size(st_dict)

        # Fetch model card (README.md) content
        model_card = ""
        try:
            card_path = await asyncio.wait_for(
                asyncio.to_thread(
                    hf_hub_download,
                    repo_id=repo_id,
                    filename="README.md",
                    endpoint=endpoint,
                ),
                timeout=_HF_API_TIMEOUT,
            )
            if card_path:
                card_text = Path(card_path).read_text(encoding="utf-8")
                # Strip YAML front matter (between --- markers)
                if card_text.startswith("---"):
                    end = card_text.find("---", 3)
                    if end != -1:
                        card_text = card_text[end + 3:].strip()
                model_card = card_text
        except Exception:
            pass  # README not available

        return {
            "repo_id": info.id,
            "name": info.id,
            "model_card": model_card,
            "description": "",  # kept for backward compat
            "files": files,
            "tags": list(info.tags) if info.tags else [],
            "pipeline_tag": info.pipeline_tag or "",
            "params": params,
            "params_formatted": params_formatted,
            "size": size,
            "size_formatted": _format_model_size(size) if size > 0 else "",
            "downloads": info.downloads or 0,
            "likes": info.likes or 0,
            "created_at": info.created_at.isoformat() if info.created_at else "",
            "updated_at": (
                info.last_modified.isoformat() if info.last_modified else ""
            ),
            "is_adapter": is_adapter,
        }

    def __init__(
        self,
        model_dir: str,
        on_complete: Optional[Callable] = None,
    ):
        self._model_dir = Path(model_dir)
        self._tasks: dict[str, DownloadTask] = {}
        self._active_tasks: dict[str, asyncio.Task] = {}
        self._progress_tasks: dict[str, asyncio.Task] = {}
        self._on_complete = on_complete
        self._cancelled: set[str] = set()
        self._download_sem = asyncio.Semaphore(1)

    @property
    def model_dir(self) -> Path:
        return self._model_dir

    def update_model_dir(self, new_dir: str) -> None:
        """Update the model directory path."""
        self._model_dir = PaodelID, mono: true, width: 220)
                    .onSubmit { Task { await vm.save(.alias, client: client) } }
            }
            Row(label: String(localized: "settings.basic.model_type.label",
                              defaultValue: "Model Type",
                              comment: "Row label for the model type override popup")) {
                Popup(
                    selection: vm.bind($vm.modelTypeOverride, save: { Task { await vm.save(.modelType, client: client) } }),
                    width: 170,
                    options: ModelSettingsScreenVM.modelTypeOptions
                )
            }
            Row(label: String(localized: "settings.basic.context_window.label",
                              defaultValue: "Context Window",
                              comment: "Row label for the context window field"),
                sublabel: String(localized: "settings.basic.context_window.sub",
                                 defaultValue: "Maximum tokens per request",
                                 comment: "Sublabel for the context window field")) {
                TextInput(text: vm.bindProfile($vm.contextLength), mono: true, suffix: "tk", width: 110)
            }
            Row(label: String(localized: "settings.basic.max_tokens.label",
                              defaultValue: "Max Tokens",
                              comment: "Row label for the max generated tokens field"),
                sublabel: String(localized: "settings.basic.max_tokens.sub",
                                 defaultValue: "Cap on generated tokens (empty = default)",
                                 comment: "Sublabel for the max generated tokens field")) {
                TextInput(text: vm.bindProfile($vm.maxTokens),
                          placeholder: String(localized: "settings.basic.max_tokens.placeholder",
                                              defaultValue: "Default",
                                              comment: "Placeholder shown when Max Tokens is empty (server default applies)"),
                          mono: true, width: 110)
            }
            Row(label: String(localized: "settings.basic.temperature.label",
                              defaultValue: "Temperature",
                              comment: "Row label for the sampling temperature field"),
                sublabel: String(localized: "settings.basic.temperature.sub",
                                 defaultValue: "Sampling randomness (≥ 0). 0 = deterministic.",
                                 comment: "Sublabel describing the temperature field range")) {
                TextInput(text: vm.bindProfile($vm.temperature), placeholder: "0.7", mono: true, width: 90)
            }
            if !vm.isDiffusionModel {
                Row(label: String(localized: "settings.basic.top_p.label",
                                  defaultValue: "Top P",
                                  comment: "Row label for the top-p nucleus sampling field"),
                    sublabel: String(localized: "settings.basic.top_p.sub",
                                     defaultValue: "Nucleus sampling cutoff (0 < p ≤ 1).",
                                     comment: "Sublabel describing the top-p valid range")) {
                    TextInput(text: vm.bindProfile($vm.topP), mono: true, width: 90)
                }
                Row(label: String(localized: "settings.basic.top_k.label",
                                  defaultValue: "Top K",
                                  comment: "Row label for the top-k sampling field"),
                    sublabel: String(localized: "settings.basic.top_k.sub",
                                     defaultValue: "Limit candidates to top K (positive integer).",
                                     comment: "Sublabel describing the top-k field")) {
                    TextInput(text: vm.bindProfile($vm.topK), mono: true, width: 90)
                }
                Row(label: String(localized: "settings.basic.min_p.label",
                                  defaultValue: "Min P",
            =============================================

            async startHFDownload() {
                const repoId = this.hfRepoId.trim();
                if (!repoId) return;

                this.hfError = '';
                this.hfSuccess = '';
                this.hfDownloading = true;
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 15000);

                try {
                    const response = await fetch('/admin/api/hf/download', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            repo_id: repoId,
                            hf_token: this.hfToken,
                        }),
                        signal: controller.signal,
                    });

                    if (response.ok) {
                        this.hfSuccess = window.t('js.success.download_started').replace('{repo_id}', repoId);
                        this.hfRepoId = '';
                        await this.loadHFTasks();
                        this.startHFRefresh();
                        setTimeout(() => { this.hfSuccess = ''; }, 5000);
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.hfError = data.detail || window.t('js.error.start_download_failed');
                    }
                } catch (err) {
                    if (err.name === 'AbortError') {
                        this.hfError = 'HuggingFace request timed out. The service may be unavailable.';
                    } else {
                        this.hfError = window.t('js.error.start_download_connection');
                    }
                    console.error('Failed to start download:', err);
                } finally {
                    clearTimeout(timeoutId);
                    this.hfDownloading = false;
                }
            },

            async loadHFTasks() {
                try {
                    const response = await fetch('/admin/api/hf/tasks');
                    if (response.ok) {
                        const data = await response.json();
                        this.hfTasks = data.tasks || [];

                        // Stop refresh if no active downloads
                        const hasActive = this.hfTasks.some(t =>
                            t.status === 'pending' || t.status === 'downloading');
                        if (!hasActive) {
                            this.stopHFRefresh();
                            // Refresh model lists when all downloads finish
                            if (this.hfTasks.some(t => t.status === 'completed')) {
                                await this.loadHFModels();
                                await this.loadModels();
                            }
                        }

                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (err) {
                    console.error('Failed to load HF tasks:', err);
                }
            },

            async loadHFModels() {
                try {
                    const response = await fetch('/admin/api/hf/models');
                    if (response.ok) {
                        const data = await response.json();
                        this.hfModels = data.models || [];
                        this.hfModelsLoaded = true;
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (err) {
                    console.error('Failed to load HF models:', err);
                }
            },

            async cancelHFDownload(taskId) {
                try {
                    const response = await fetch(`/admin/api/hf/cancel/${t------------------------------------
template <typename T, int group_size, bool USE_SIGMA = false>
METAL_FUNC void qmv_fast_t5_impl(
    const device uint8_t* w,
    const device T* scales,
    const device T* x,            // pre-scaled by 4^{-(j%5)} when USE_SIGMA
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    const device float* sigma,    // [n_groups] group sums; used iff USE_SIGMA
    threadgroup const uint* lut,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {

  constexpr int bytes_per_group = (group_size + 4) / 5;
  constexpr int full_bytes = group_size / 5;         // 25 for gs=128
  constexpr int chunk_bytes = full_bytes & ~3;       // 24: packed_uchar4 part
  constexpr int tail_full   = full_bytes - chunk_bytes; // 1 full byte in tail
  constexpr int rem_trits   = group_size % 5;        // 3 for gs=128
  constexpr int num_simdgroups = 4;
  constexpr int results_per_simdgroup = 4;

  typedef float U;
  constexpr U PS0 = 1.0f, PS1 = 0.25f, PS2 = 0.0625f,
              PS3 = 0.015625f, PS4 = 0.00390625f;

  thread U result[results_per_simdgroup] = {0};
  const int n_groups = in_vec_size / group_size;
  const int out_row  = tid.y * (num_simdgroups * results_per_simdgroup) +
                       simd_gid * results_per_simdgroup;
  const int ng_bpg   = n_groups * bytes_per_group;

  int rows[results_per_simdgroup];
  bool row_ok[results_per_simdgroup];
  for (int r = 0; r < results_per_simdgroup; r++) {
    row_ok[r] = (out_row + r) < out_vec_size;
    rows[r]   = row_ok[r] ? (out_row + r) : 0;
  }

  const device T* x_batch = x + tid.x * in_vec_size;

  for (int g = simd_lid; g < n_groups; g += SIMD_SIZE) {
    const device T* xg = x_batch + g * group_size;
    const device uint8_t* wg0 = w + rows[0]*ng_bpg + g*bytes_per_group;
    const device uint8_t* wg1 = w + rows[1]*ng_bpg + g*bytes_per_group;
    const device uint8_t* wg2 = w + rows[2]*ng_bpg + g*bytes_per_group;
    const device uint8_t* wg3 = w + rows[3]*ng_bpg + g*bytes_per_group;
    const U s0 = U(scales[rows[0]*n_groups + g]);
    const U s1 = U(scales[rows[1]*n_groups + g]);
    const U s2 = U(scales[rows[2]*n_groups + g]);
    const U s3 = U(scales[rows[3]*n_groups + g]);

    U a0 = 0, a1 = 0, a2 = 0, a3 = 0, x_sum = 0;

#pragma clang loop unroll(full)
    for (int c = 0; c < chunk_bytes / 4; c++) {
      const packed_uchar4 q0 = *((const device packed_uchar4*)(wg0 + c*4));
      const packed_uchar4 q1 = *((const device packed_uchar4*)(wg1 + c*4));
      const packed_uchar4 q2 = *((const device packed_uchar4*)(wg2 + c*4));
      const packed_uchar4 q3 = *((const device packed_uchar4*)(wg3 + c*4));
#pragma clang loop unroll(full)
      for (int bb = 0; bb < 4; bb++) {
        const uint p0 = lut[q0[bb]], p1 = lut[q1[bb]];
        const uint p2 = lut[q2[bb]], p3 = lut[q3[bb]];
        const int base = (c*4 + bb) * 5;
        const packed_half4 xv4 = *((const device packed_half4*)(xg + base));
        const U xv0 = U(xv4[0]), xv1 = U(xv4[1]), xv2 = U(xv4[2]), xv3 = U(xv4[3]);
        const U xv4s = U(xg[base + 4]);
        U xp1, xp2, xp3, xp4;
        if constexpr (USE_SIGMA) { xp1=xv1; xp2=xv2; xp3=xv3; xp4=xv4s; }
        else { x_sum += xv0+xv1+xv2+xv3+xv4s; xp1=xv1*PS1; xp2=xv2*PS2; xp3=xv3*PS3; xp4=xv4s*PS4; }
        a0+=xv0*U(p0&0x003u)+xp1*U(p0&0x00Cu)+xp2*U(p0&0x030u)+xp3*U(p0&0x0C0u)+xp4*U(p0&0x300u);
        a1+=xv0*U(p1&0x003u)+xp1*U(p1&0x00Cu)+xp2*U(p1&0x030u)+xp3*U(p1&0x0C0u)+xp4*U(p1&0x300u);
        a2+=xv0*U(p2&0x003u)+xp1*U(p2&0x00Cu)+xp2*U(p2&0x030u)+xp3*U(p2&0x0C0u)+xp4*U(p2&0x300u);
        a3+=xv0*U(p3&0x003u)+xp1*U(p3&0x00Cu)+xp2*U(p3&0x030u)+xp3*U(p3&0x0C0u)+xp4*U(p3&0x300u);
      }
    }
    if constexpr (tail_full > 0 || rem_trits > 0) {
      ushort t0, t1, t2, t3;
      if constexpr (tail_full > 0) {
        t0 = *((const device ushort*)(wg0 + chunk_bytes));
        t1 = *((const device ushort*)(wg1 + chunk_bytes));
        t2 = *((const device ushort*)(wg2 + chunk_bytes)th(new_dir)

    async def start_download(
        self, repo_id: str, hf_token: str = ""
    ) -> DownloadTask:
        """Start downloading a model from HuggingFace.

        Args:
            repo_id: HuggingFace repository ID (e.g., "mlx-community/Llama-3-8B-4bit").
            hf_token: Optional HuggingFace token for gated models.

        Returns:
            The created DownloadTask.

        Raises:
            ValueError: If repo_id format is invalid or download is already queued.
        """
        repo_id = repo_id.strip()
        if "/" not in repo_id or len(repo_id.split("/")) != 2:
            raise ValueError(
                f"Invalid repository ID: '{repo_id}'. "
                "Expected format: 'owner/model' (e.g., 'mlx-community/Llama-3-8B-4bit')"
            )

        # Check for duplicate active downloads
        for task in self._tasks.values():
            if task.repo_id == repo_id and task.status in (
                DownloadStatus.PENDING,
                DownloadStatus.DOWNLOADING,
            ):
                raise ValueError(
                    f"Download for '{repo_id}' is already in progress"
                )

        task_id = str(uuid.uuid4())
        task = DownloadTask(task_id=task_id, repo_id=repo_id)
        self._tasks[task_id] = task

        # Start download in background
        self._active_tasks[task_id] = asyncio.create_task(
            self._run_download(task_id, hf_token)
        )

        logger.info(f"Download queued: {repo_id} (task_id={task_id})")
        return task

    async def cancel_download(self, task_id: str) -> bool:
        """Cancel an active download.

        Args:
            task_id: The task ID to cancel.

        Returns:
            True if the task was found and cancelled.
        """
        task = self._tasks.get(task_id)
        if task is None:
            return False

        if task.status not in (DownloadStatus.PENDING, DownloadStatus.DOWNLOADING):
            return False

        was_downloading = task.status == DownloadStatus.DOWNLOADING

        # Mark as cancelled
        self._cancelled.add(task_id)
        task.status = DownloadStatus.CANCELLED

        # A task in DOWNLOADING owns the download semaphore, so the in-flight
        # xet transfer is necessarily this one; aborting the (global) session
        # makes its snapshot_download thread unwind immediately. Pending tasks
        # must not abort, that would kill another task's transfer. The next
        # download lazily creates a fresh session.
        if was_downloading:
            abort_xet_session()

        # Stop progress polling
        progress_task = self._progress_tasks.pop(task_id, None)
        if progress_task and not progress_task.done():
            progress_task.cancel()

        # Cancel the download task
        active_task = self._active_tasks.pop(task_id, None)
        if active_task and not active_task.done():
            active_task.cancel()

        logger.info(f"Download cancelled: {task.repo_id} (task_id={task_id})")
        return True

    def remove_task(self, task_id: str) -> bool:
        """Remove a completed, failed, or cancelled task from the list.

        Args:
            task_id: The task ID to remove.

        Returns:
            True if the task was found and removed.
        """
        task = self._tasks.get(task_id)
        if task is None:
            return False

        if task.status in (DownloadStatus.PENDING, DownloadStatus.DOWNLOADING):
            return False

        del self._tasks[task_id]
        self._cancelled.discard(task_id)
        return True

    async def retry_download(
        self, task_id: str, hf_token: str = ""
    ) -> DownloadTask:
        """Retry a failed or cancelled download, resuming from existing files.

        Finalized shards are preserved on disk so snapshot_download will
        automatically skip already-completed files.

        Args:
            task_id: The task ID of the failed/cancelled download.
            hf_token: Optional HuggingFace token for gated models.

        Returns:
                           comment: "Row label for the min-p sampling field"),
                    sublabel: String(localized: "settings.basic.min_p.sub",
                                     defaultValue: "Minimum probability floor (0 ≤ p ≤ 1).",
                                     comment: "Sublabel describing the min-p field range")) {
                    TextInput(text: vm.bindProfile($vm.minP), mono: true, width: 90)
                }
                Row(label: String(localized: "settings.basic.repetition_penalty.label",
                                  defaultValue: "Repetition Penalty",
                                  comment: "Row label for the repetition-penalty field"),
                    sublabel: vm.vlmMtpEnabled
                        ? vm.vlmMtpProcessorLockedReason
                        : String(localized: "settings.basic.repetition_penalty.sub",
                                 defaultValue: "Penalize repeated tokens (−2 to 2).",
                                 comment: "Sublabel describing repetition-penalty range")) {
                    TextInput(text: vm.bindProfile($vm.repetitionPenalty), mono: true, width: 90)
                        .disabled(vm.vlmMtpEnabled)
                        .help(vm.vlmMtpEnabled ? vm.vlmMtpProcessorLockedReason : "")
                }
                Row(label: String(localized: "settings.basic.presence_penalty.label",
                                  defaultValue: "Presence Penalty",
                                  comment: "Row label for the presence-penalty field"),
                    sublabel: vm.vlmMtpEnabled
                        ? vm.vlmMtpProcessorLockedReason
                        : String(localized: "settings.basic.presence_penalty.sub",
                                 defaultValue: "Penalize tokens already present (−2 to 2).",
                                 comment: "Sublabel describing presence-penalty range")) {
                    TextInput(text: vm.bindProfile($vm.presencePenalty), mono: true, width: 90)
                        .disabled(vm.vlmMtpEnabled)
                        .help(vm.vlmMtpEnabled ? vm.vlmMtpProcessorLockedReason : "")
                }
            }
            Row(
                label: String(localized: "settings.basic.ttl.label",
                              defaultValue: "TTL",
                              comment: "Row label for the idle-unload TTL field"),
                sublabel: String(localized: "settings.basic.ttl.sub",
                                 defaultValue: "Seconds before idle unload (empty = no TTL)",
                                 comment: "Sublabel for the idle-unload TTL field"),
                isLast: true
            ) {
                TextInput(text: $vm.ttlSeconds,
                          placeholder: String(localized: "settings.basic.ttl.placeholder",
                                              defaultValue: "No TTL",
                                              comment: "Placeholder shown when no TTL is configured"),
                          mono: true, suffix: "s", width: 110)
                    .onSubmit { Task { await vm.save(.ttl, client: client) } }
            }
        }
    }
}

/// Slim ActiveProfileBanner used above Basic / Advanced editors so the user
/// can save without bouncing back to the Profiles tab. Renders nothing in
/// the `named` (clean) state — no banner clutter when there's nothing to
/// do.
private struct BasicEditBanner: View {
    var vm: ModelSettingsScreenVM
    let client: OMLXClient

    @State private var saveAsScope: ProfileScope = .global
    @State private var saveAsName: String = ""
    @State private var saveAsOpen: Bool = false

    var body: some View {
        switch vm.activeProfileState {
        case .named:
            EmptyView()
        default:
            VStack(alignment: .leading, spacing: 0) {
                ActiveProfileBanner(
                    state: vm.activeProfileState,
                    isSlim: true,
                    onUpdateBasedOn: {
                        if case .working(let basedOn) = vm.activeProfileStaaskId}`, {
                        method: 'POST',
                    });
                    if (response.ok) {
                        await this.loadHFTasks();
                    }
                } catch (err) {
                    console.error('Failed to cancel download:', err);
                }
            },

            async retryHFDownload(taskId) {
                try {
                    const response = await fetch(`/admin/api/hf/retry/${taskId}`, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ hf_token: this.hfToken || '' }),
                    });
                    if (response.ok) {
                        await this.loadHFTasks();
                        this.startHFRefresh();
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.hfError = data.detail || 'Retry failed';
                        setTimeout(() => { this.hfError = ''; }, 5000);
                    }
                } catch (err) {
                    console.error('Failed to retry download:', err);
                }
            },

            async removeHFTask(taskId) {
                try {
                    const response = await fetch(`/admin/api/hf/task/${taskId}`, {
                        method: 'DELETE',
                    });
                    if (response.ok) {
                        await this.loadHFTasks();
                    }
                } catch (err) {
                    console.error('Failed to remove task:', err);
                }
            },

            async deleteHFModel(modelName) {
                this.hfDeleteConfirm = null;
                try {
                    const response = await fetch(`/admin/api/hf/models/${encodeURIComponent(modelName)}`, {
                        method: 'DELETE',
                    });
                    if (response.ok) {
                        await this.loadHFModels();
                        await this.loadModels();
                    } else {
                        const data = await response.json();
                        this.hfError = data.detail || window.t('js.error.delete_model_failed');
                        setTimeout(() => { this.hfError = ''; }, 5000);
                    }
                } catch (err) {
                    console.error('Failed to delete model:', err);
                    this.hfError = window.t('js.error.delete_model_connection');
                    setTimeout(() => { this.hfError = ''; }, 5000);
                }
            },

            startHFRefresh() {
                this.stopHFRefresh();
                this._hfRefreshTimer = setInterval(() => {
                    this.loadHFTasks();
                }, 2000);
            },

            stopHFRefresh() {
                if (this._hfRefreshTimer) {
                    clearInterval(this._hfRefreshTimer);
                    this._hfRefreshTimer = null;
                }
            },

            formatProgress(task) {
                const pct = Math.round(task.progress || 0);
                const dlGB = (task.downloaded_size / (1024 ** 3)).toFixed(1);
                const totalGB = (task.total_size / (1024 ** 3)).toFixed(1);
                return `${pct}% \u00b7 ${dlGB} GB / ${totalGB} GB`;
            },

            // =================================================================
            // oQ Quantization Functions
            // =================================================================

            async loadOQModels() {
                try {
                    const response = await fetch('/admin/api/oq/models');
                    if (response.ok) {
                        const data = await response.json();
                        this.oqModels = data.models || [];
                        this.oqAllModels = data.all_models || [];
                        this.oqModelsLoaded = true;
                    }
                } catch (err) {
  );
        t3 = *((const device ushort*)(wg3 + chunk_bytes));
      } else {
        t0 = ushort(wg0[chunk_bytes]) << 8; t1 = ushort(wg1[chunk_bytes]) << 8;
        t2 = ushort(wg2[chunk_bytes]) << 8; t3 = ushort(wg3[chunk_bytes]) << 8;
      }
      if constexpr (tail_full > 0) {
        const uint p0=lut[t0&0xFF], p1=lut[t1&0xFF], p2=lut[t2&0xFF], p3=lut[t3&0xFF];
        const int base = chunk_bytes * 5;
        const packed_half4 xv4 = *((const device packed_half4*)(xg + base));
        const U xv0=U(xv4[0]), xv1=U(xv4[1]), xv2=U(xv4[2]), xv3=U(xv4[3]), xv4s=U(xg[base+4]);
        U xp1,xp2,xp3,xp4;
        if constexpr (USE_SIGMA) { xp1=xv1;xp2=xv2;xp3=xv3;xp4=xv4s; }
        else { x_sum+=xv0+xv1+xv2+xv3+xv4s; xp1=xv1*PS1;xp2=xv2*PS2;xp3=xv3*PS3;xp4=xv4s*PS4; }
        a0+=xv0*U(p0&0x003u)+xp1*U(p0&0x00Cu)+xp2*U(p0&0x030u)+xp3*U(p0&0x0C0u)+xp4*U(p0&0x300u);
        a1+=xv0*U(p1&0x003u)+xp1*U(p1&0x00Cu)+xp2*U(p1&0x030u)+xp3*U(p1&0x0C0u)+xp4*U(p1&0x300u);
        a2+=xv0*U(p2&0x003u)+xp1*U(p2&0x00Cu)+xp2*U(p2&0x030u)+xp3*U(p2&0x0C0u)+xp4*U(p2&0x300u);
        a3+=xv0*U(p3&0x003u)+xp1*U(p3&0x00Cu)+xp2*U(p3&0x030u)+xp3*U(p3&0x0C0u)+xp4*U(p3&0x300u);
      }
      if constexpr (rem_trits > 0) {
        const uint p0=lut[t0>>8], p1=lut[t1>>8], p2=lut[t2>>8], p3=lut[t3>>8];
        const int base = full_bytes * 5;
#pragma clang loop unroll(full)
        for (int k = 0; k < rem_trits; k++) {
          const U xv=U(xg[base+k]); U xp;
          if constexpr (USE_SIGMA) { xp=xv; }
          else { x_sum+=xv; xp=xv*(k==0?PS0:k==1?PS1:k==2?PS2:k==3?PS3:PS4); }
          const uint m=0x3u<<(2*k);
          a0+=xp*U(p0&m); a1+=xp*U(p1&m); a2+=xp*U(p2&m); a3+=xp*U(p3&m);
        }
      }
    }
    const U xs = USE_SIGMA ? U(sigma[g]) : x_sum;
    result[0] += s0*(a0-xs); result[1] += s1*(a1-xs);
    result[2] += s2*(a2-xs); result[3] += s3*(a3-xs);
  }
  for (int row = 0; row < results_per_simdgroup; row++) {
    result[row] = simd_sum(result[row]);
    if (simd_lid == 0 && row_ok[row])
      y[tid.x * out_vec_size + out_row + row] = T(result[row]);
  }
}


// qmv_wide_t5: small-batch decode (M = vecs_per_tg = 2..5).
//
// Amortises the weight stream across all M vectors (Identity I-C):
// decode each t5 byte once, multiply with all M activations.
// k_lanes threads stride over groups, results_per_simdgroup=SIMD_SIZE/k_lanes.
template <typename T, int group_size, int vecs_per_tg, int k_lanes>
METAL_FUNC void qmv_wide_t5_impl(
    const device uint8_t* w,
    const device T* scales,
    const device T* x,
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    const constant int& M,
    threadgroup const uint* lut,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {

  constexpr int bytes_per_group = (group_size + 4) / 5;
  constexpr int full_bytes = group_size / 5;
  constexpr int rem_trits  = group_size % 5;
  constexpr int num_simdgroups = 4;
  constexpr int results_per_simdgroup = SIMD_SIZE / k_lanes;

  typedef float U;
  const short k_lane = simd_lid % k_lanes;
  const short sg_row = simd_lid / k_lanes;

  const int out_row = tid.y * (results_per_simdgroup * num_simdgroups) +
                      results_per_simdgroup * simd_gid + sg_row;
  const int vec0 = tid.x * vecs_per_tg;
  const int n_groups = in_vec_size / group_size;

  const int row = min(out_row, out_vec_size - 1);
  const device uint8_t* wrow = w + row * (n_groups * bytes_per_group);
  const device T* srow = scales + row * n_groups;

  const device T* xv[vecs_per_tg];
  for (int v = 0; v < vecs_per_tg; v++) {
    xv[v] = x + min(vec0 + v, M - 1) * in_vec_size;
  }

  U result[vecs_per_tg] = {0};

  for (int g = k_lane; g < n_groups; g += k_lanes) {
    const device uint8_t* wg = wrow + g * bytes_per_group;
    const U s = U(srow[g]);
    const int k0 = g * group_size;

    // Full bytes: T5_TO_B4 LUT replaces serial divmod chain; all 5 dq values
    // are independent (no v=q reassignment), hiding decode latency.
    for (i       The new DownloadTask.

        Raises:
            ValueError: If task not found or not in retryable state.
        """
        old_task = self._tasks.get(task_id)
        if old_task is None:
            raise ValueError(f"Task not found: {task_id}")

        if old_task.status not in (DownloadStatus.FAILED, DownloadStatus.CANCELLED):
            raise ValueError(
                f"Task {task_id} is not retryable (status: {old_task.status.value})"
            )

        repo_id = old_task.repo_id
        old_retry_count = old_task.retry_count

        # Remove old task entry
        del self._tasks[task_id]
        self._cancelled.discard(task_id)

        # Start fresh download (snapshot_download resumes from existing files)
        new_task = await self.start_download(repo_id, hf_token)
        new_task.retry_count = old_retry_count + 1
        return new_task

    def get_tasks(self) -> list[dict]:
        """Return all tasks as serializable dicts, ordered by creation time."""
        return [
            task.to_dict()
            for task in sorted(self._tasks.values(), key=lambda t: t.created_at)
        ]

    async def shutdown(self) -> None:
        """Cancel all active downloads and clean up."""
        # Cancel all progress polling tasks
        for task_id, progress_task in list(self._progress_tasks.items()):
            if not progress_task.done():
                progress_task.cancel()
        self._progress_tasks.clear()

        # Cancel all active download tasks. Mark cancelled first so an
        # in-flight snapshot_download thread aborts via its progress callback;
        # active_task.cancel() only unblocks tasks still waiting on the semaphore.
        for task_id, active_task in list(self._active_tasks.items()):
            self._cancelled.add(task_id)
            if not active_task.done():
                active_task.cancel()
                task = self._tasks.get(task_id)
                if task and task.status == DownloadStatus.DOWNLOADING:
                    task.status = DownloadStatus.CANCELLED
        self._active_tasks.clear()

        # Reap any in-flight xet transfer thread (no-op without a session).
        abort_xet_session()

        logger.info("HF Downloader shut down")

    async def _run_download(self, task_id: str, hf_token: str) -> None:
        """Execute a download task.

        Waits for the download semaphore (only one download runs at a time),
        then fetches repo info for total size and runs snapshot_download in a
        thread while polling the target directory for progress updates.
        """
        task = self._tasks[task_id]

        try:
            async with self._download_sem:
                # Check if cancelled while waiting in queue
                if task_id in self._cancelled:
                    return

                task.status = DownloadStatus.DOWNLOADING
                task.started_at = time.time()

                # Preserve {owner}/{model} layout to match other tools
                # (LMStudio, huggingface-cli) and avoid duplicate downloads
                # when sharing a model directory.
                target_dir = self._model_dir / task.repo_id

                api, endpoint = _get_hf_api()

                # Skip pytorch format when safetensors exist to
                # avoid downloading redundant weight files.
                ignore_patterns = None
                st_estimate = 0
                try:
                    model_info = await asyncio.wait_for(
                        asyncio.to_thread(
                            api.model_info,
                            task.repo_id,
                            token=hf_token or None,
                            expand=["safetensors"],
                        ),
                        timeout=_HF_API_TIMEOUT,
                    )
                    if model_info.safetensors and model_info.safetensors.get(
                        "parameters"
                    ):
                        ignore_patterns = [
                            "*.bin",
                            "orite, let basedOn {
                            Task {
                                await vm.updateProfileWithWorking(
                                    scope: basedOn.scope, name: basedOn.name, client: client
                                )
                            }
                        }
                    },
                    onSaveAsNew: {
                        saveAsScope = .global
                        saveAsName = vm.suggestSaveAsName()
                        saveAsOpen = true
                    },
                    onRevert: {
                        Task { await vm.revertWorking(client: client) }
                    }
                )
                if saveAsOpen {
                    SaveAsPopover(
                        name: $saveAsName,
                        scope: $saveAsScope,
                        onCommit: {
                            Task {
                                await vm.saveWorkingAs(
                                    scope: saveAsScope, name: saveAsName, client: client
                                )
                                saveAsOpen = false
                            }
                        },
                        onCancel: { saveAsOpen = false }
                    )
                }
            }
        }
    }
}

// MARK: - Advanced tab

private struct AdvancedTab: View {
    @Bindable var vm: ModelSettingsScreenVM
    let client: OMLXClient

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        BasicEditBanner(vm: vm, client: client)
        SectionHeader(String(localized: "settings.advanced.section",
                             defaultValue: "Advanced Settings",
                             comment: "Section header above the Advanced tab fields"))

        // Profile-eligible toggles use `bindProfile` — flipping them flips
        // the working-dirty flag. `isPinned` and `trustRemoteCode` stay
        // per-model (server excludes them from profiles) and auto-save.
        ListGroup {
            if !vm.isDiffusionModel {
                Row(label: String(localized: "settings.advanced.enable_thinking.label",
                                  defaultValue: "Enable Thinking",
                                  comment: "Row label for the enable-thinking toggle"),
                    sublabel: String(localized: "settings.advanced.enable_thinking.sub",
                                     defaultValue: "Enable reasoning/thinking mode for this model",
                                     comment: "Sublabel for the enable-thinking toggle")) {
                    Toggle("", isOn: vm.bindProfile($vm.enableThinking))
                        .labelsHidden().toggleStyle(.switch)
                }
                Row(label: String(localized: "settings.advanced.thinking_budget.label",
                                  defaultValue: "Thinking Budget",
                                  comment: "Row label for the thinking budget field"),
                    sublabel: vm.vlmMtpEnabled
                        ? vm.vlmMtpProcessorLockedReason
                        : String(localized: "settings.advanced.thinking_budget.sub",
                                 defaultValue: "Limit thinking tokens for reasoning models. Forces end of thinking when exceeded.",
                                 comment: "Sublabel for the thinking budget field")) {
                    HStack(spacing: 8) {
                        if vm.thinkingBudgetEnabled {
                            TextInput(text: vm.bindProfile($vm.thinkingBudgetTokens),
                                      mono: true, suffix: "tk", width: 110)
                        }
                        Toggle("", isOn: vm.bindProfile($vm.thinkingBudgetEnabled))
                            .labelsHidden().toggleStyle(.switch)
                    }
                    .disabled(vm.vlmMtpEnabled)
                    .help(vm.vlmMtpEnabled ? vm.vlmMtpProcessorLockedReason : "")
                }
                Row(label: String(localized: "settings.advanced.tool_result_limit.label",
                     console.error('Failed to load quantizable models:', err);
                }
            },

            async startOQQuantization() {
                if (!this.oqSelectedModelPath || this.oqStarting) return;
                this.oqError = '';
                this.oqSuccess = '';
                this.oqStarting = true;
                try {
                    const payload = {
                        model_path: this.oqSelectedModelPath,
                        oq_level: this.oqLevel,
                        group_size: 64,
                        sensitivity_model_path: this.oqSensitivityModelPath,
                        text_only: this.oqTextOnly,
                        dtype: this.oqDtype,
                        preserve_mtp: this.oqSelectedModelHasMtp() ? this.oqPreserveMtp : false,
                        mtp_assistant_model_path: this.oqMtpAssistantCandidates().some(m => m.path === this.oqMtpAssistantPath)
                            ? this.oqMtpAssistantPath : '',
                    };
                    if (this.oqEnhanced) {
                        payload.enhanced = true;
                        payload.imatrix_reuse_cache = this.oqeReuseImatrixCache;
                        payload.imatrix_cache_path = this.oqeImatrixCachePath.trim();
                        payload.imatrix_strict = this.oqeStrictImatrix;
                    }
                    const response = await fetch('/admin/api/oq/start', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(payload),
                    });
                    const data = await response.json().catch(() => ({}));
                    if (response.ok) {
                        const model = this.oqModels.find(m => m.path === this.oqSelectedModelPath);
                        const name = model ? model.name : this.oqSelectedModelPath;
                        this.oqSuccess = `Quantization started: ${name} → oQ${this.oqLevel}${this.oqEnhanced ? 'e' : ''}`;
                        await this.loadOQTasks();
                        this.startOQRefresh();
                        setTimeout(() => { this.oqSuccess = ''; }, 5000);
                    } else {
                        this.oqError = data.detail || 'Failed to start quantization';
                    }
                } catch (err) {
                    this.oqError = 'Connection error. Server may be unavailable.';
                } finally {
                    this.oqStarting = false;
                }
            },

            async loadOQTasks() {
                try {
                    const response = await fetch('/admin/api/oq/tasks');
                    if (response.ok) {
                        const data = await response.json();
                        this.oqTasks = data.tasks || [];
                        const hasActive = this.oqTasks.some(t =>
                            ['pending', 'loading', 'quantizing', 'saving'].includes(t.status));
                        if (!hasActive) {
                            this.stopOQRefresh();
                            if (this.oqTasks.some(t => t.status === 'completed')) {
                                await this.loadHFModels();
                                await this.loadModels();
                                await this.loadOQModels();
                            }
                        }
                    }
                } catch (err) {
                    console.error('Failed to load oQ tasks:', err);
                }
            },

            async cancelOQTask(taskId) {
                try {
                    await fetch(`/admin/api/oq/cancel/${taskId}`, { method: 'POST' });
                    await this.loadOQTasks();
                } catch (err) {
                    console.error('Failed to cancel oQ task:', err);
                }
            },

            async removeOQTask(taskId) {
                try {
                    await fetch(`/admin/api/oq/task/${taskId}`, { method: 'DELETE' });
       nt b = 0; b < full_bytes; b++) {
      const uint p = T5_TO_B4[wg[b]];
      const int base = k0 + b * 5;
      const U dq0 = s * (U(p & 0x003u)        - 1.0f);
      const U dq1 = s * (U((p >>  2u) & 0x3u) - 1.0f);
      const U dq2 = s * (U((p >>  4u) & 0x3u) - 1.0f);
      const U dq3 = s * (U((p >>  6u) & 0x3u) - 1.0f);
      const U dq4 = s * (U((p >>  8u) & 0x3u) - 1.0f);
#pragma unroll
      for (int vi = 0; vi < vecs_per_tg; vi++) {
        result[vi] += U(xv[vi][base + 0]) * dq0
                    + U(xv[vi][base + 1]) * dq1
                    + U(xv[vi][base + 2]) * dq2
                    + U(xv[vi][base + 3]) * dq3
                    + U(xv[vi][base + 4]) * dq4;
      }
    }
    // Last partial byte via T5_TO_B4 LUT.
    if constexpr (rem_trits > 0) {
      const uint p = T5_TO_B4[wg[full_bytes]];
      const int base = k0 + full_bytes * 5;
      U dq0 = U(0), dq1 = U(0), dq2 = U(0), dq3 = U(0);
      if constexpr (rem_trits >= 1) { dq0 = s * (U(p & 0x003u) - 1.0f); }
      if constexpr (rem_trits >= 2) { dq1 = s * (U((p >> 2u) & 0x3u) - 1.0f); }
      if constexpr (rem_trits >= 3) { dq2 = s * (U((p >> 4u) & 0x3u) - 1.0f); }
      if constexpr (rem_trits >= 4) { dq3 = s * (U((p >> 6u) & 0x3u) - 1.0f); }
#pragma unroll
      for (int vi = 0; vi < vecs_per_tg; vi++) {
        if constexpr (rem_trits >= 1) result[vi] += U(xv[vi][base + 0]) * dq0;
        if constexpr (rem_trits >= 2) result[vi] += U(xv[vi][base + 1]) * dq1;
        if constexpr (rem_trits >= 3) result[vi] += U(xv[vi][base + 2]) * dq2;
        if constexpr (rem_trits >= 4) result[vi] += U(xv[vi][base + 3]) * dq3;
      }
    }
  }

  // k_lane shuffle reduction (same ladder as qmv_wide_impl).
  for (int v = 0; v < vecs_per_tg; v++) {
    if constexpr (k_lanes >= 32) result[v] += simd_shuffle_down(result[v], 16);
    if constexpr (k_lanes >= 16) result[v] += simd_shuffle_down(result[v], 8);
    if constexpr (k_lanes >= 8)  result[v] += simd_shuffle_down(result[v], 4);
    if constexpr (k_lanes >= 4)  result[v] += simd_shuffle_down(result[v], 2);
    if constexpr (k_lanes >= 2)  result[v] += simd_shuffle_down(result[v], 1);
  }

  if (k_lane == 0 && out_row < out_vec_size) {
    for (int v = 0; v < vecs_per_tg; v++) {
      if (vec0 + v < M) {
        y[(vec0 + v) * out_vec_size + out_row] = T(result[v]);
      }
    }
  }
}

// ---------------------------------------------------------------------------
// qmm_t5_impl: simdgroup MMA GEMM for t5 ternary weights (Identity I-M).
//
// Computes out[M, N] = x[M, K] @ t5_decode(w[N, K]).T  (float32 accumulate).
//
// Architecture (adapted from MetalTile mt_qmm_mma_int2):
//   BM=BN=32, BK=group_size (one complete t5 group per K-block iteration)
//   128 threads = 4 SG × 32 lanes; 2×2 SG tile layout (sm=sg/2, sn=sg%2)
//   xs[BM][BK+4] and ws[BN][BK+4] threadgroup tiles
//   BK/8 simdgroup_multiply_accumulate calls per K-block
//
// Thread (lane_in_tg = sg_id*32 + lane):
//   X loading :  row = lane_in_tg/4, k_sub = lane_in_tg%4 → loads BK/4 x-elems
//   W dequant :  row = lane_in_tg/4, sub  = lane_in_tg%4 → decodes BK/4 trits
//                (sub 0..3 each decode a contiguous BK/4 K-positions from t5 bytes)
//
// Grid: (ceil(N/32), ceil(M/32), B)  Threadgroup: (32, 4, 1)
// ---------------------------------------------------------------------------
template <typename T, int group_size>
METAL_FUNC void qmm_t5_impl(
    const device uint8_t* w,    // (N, n_groups * bpg) t5 bytes
    const device T* scales,     // (N, n_groups)
    const device T* x,          // (M, K)
    device T* out,              // (M, N)
    const constant int& M_c,
    const constant int& N_c,
    const constant int& K_c,
    threadgroup T* xs,          // BM*(group_size+4) — declared by caller
    threadgroup T* ws,          // BN*(group_size+4) — declared by caller
    uint2 tgid,                  // (n_tile, m_tile)
    uint  lane,                  // thread_index_in_simdgroup  (0..31)
    uint  sg_id)                 // simdgroup_index_in_threadgroup (0..3)
{
  constexpr int bpg    = (group_size + 4) / 5;   // bytes per groginal/**",
                            "consolidated.*.pth",
                        ]
                        # Computed inside this try so malformed metadata
                        # (non-int counts) degrades to no estimate instead
                        # of failing the download from the dry-run handler.
                        st_estimate = _calc_safetensors_disk_size(
                            model_info.safetensors
                        )
                except Exception as e:
                    logger.warning(
                        f"Could not fetch repo info for {task.repo_id}: {e}"
                    )

                dl_kwargs: dict = {
                    "repo_id": task.repo_id,
                    "local_dir": str(target_dir),
                    "token": hf_token or None,
                    "endpoint": endpoint,
                    "etag_timeout": 30,
                }
                if ignore_patterns:
                    dl_kwargs["ignore_patterns"] = ignore_patterns

                # Get accurate total size via dry run so the progress
                # denominator matches what will actually be downloaded.
                size_estimated = False
                try:
                    dry_result = await asyncio.wait_for(
                        asyncio.to_thread(
                            snapshot_download,
                            **dl_kwargs,
                            dry_run=True,
                        ),
                        timeout=30,
                    )
                    task.total_size = sum(f.file_size for f in dry_result)
                except Exception as e:
                    if st_estimate:
                        task.total_size = st_estimate
                        size_estimated = True
                        detail = "Estimated total size from safetensors metadata."
                    else:
                        detail = "Progress estimation will be unavailable."
                    logger.warning(
                        f"Dry run failed for {task.repo_id}: {e}. {detail}"
                    )

                # Start progress polling
                self._progress_tasks[task_id] = asyncio.create_task(
                    self._poll_progress(task_id, target_dir)
                )

                # Run snapshot_download in a thread (blocking call). Cancel
                # reaches the thread two ways: the cancellable tqdm raises on
                # the next chunk of the http_get path, and abort_xet_session()
                # (called by cancel/stall/shutdown) unwinds the xet path with
                # a RuntimeError (the thread itself can't be force-killed).
                await asyncio.to_thread(
                    snapshot_download,
                    **dl_kwargs,
                    tqdm_class=_make_cancellable_tqdm(
                        lambda: task_id in self._cancelled
                    ),
                )

                # Check if cancelled while downloading
                if task_id in self._cancelled:
                    return

                # Success
                task.status = DownloadStatus.COMPLETED
                task.progress = 100.0
                if size_estimated or not task.total_size:
                    # The estimate was only a progress denominator; report
                    # the measured on-disk size once the download is done.
                    task.downloaded_size = self._get_dir_size(target_dir)
                else:
                    task.downloaded_size = task.total_size
                task.completed_at = time.time()

                logger.info(
                    f"Download completed: {task.repo_id} -> {target_dir} "
                    f"({time.time() - task.started_at:.1f}s)"
                )

                # Trigger model pool refresh
                if self._on_complete:
                    try:
                        await self._on_complete()
                    except Exception as e:
                        logger.error(
                            f"Error in download completion callbac                               defaultValue: "Limit Tool Result Tokens",
                                  comment: "Row label for the tool-result token limit field"),
                    sublabel: String(localized: "settings.advanced.tool_result_limit.sub",
                                     defaultValue: "Truncate large tool results (e.g. file reads) to a token limit",
                                     comment: "Sublabel for the tool-result token limit field")) {
                    HStack(spacing: 8) {
                        if vm.limitToolResults {
                            TextInput(text: vm.bindProfile($vm.toolResultLimitTokens),
                                      placeholder: "4096",
                                      mono: true, suffix: "tk", width: 110)
                        }
                        Toggle("", isOn: vm.bindProfile($vm.limitToolResults))
                            .labelsHidden().toggleStyle(.switch)
                    }
                }
                Row(label: String(localized: "settings.advanced.force_sampling.label",
                                  defaultValue: "Force Sampling",
                                  comment: "Row label for the force-sampling toggle"),
                    sublabel: String(localized: "settings.advanced.force_sampling.sub",
                                     defaultValue: "Override request sampling parameters with configured values",
                                     comment: "Sublabel for the force-sampling toggle")) {
                    Toggle("", isOn: vm.bindProfile($vm.forceSampling))
                        .labelsHidden().toggleStyle(.switch)
                }
                Row(label: String(localized: "settings.advanced.reasoning_parser.label",
                                  defaultValue: "Reasoning Parser",
                                  comment: "Row label for the reasoning-parser override field"),
                    sublabel: String(localized: "settings.advanced.reasoning_parser.sub",
                                     defaultValue: "Override the chain-of-thought parser. Leave empty to use the model's default.",
                                     comment: "Sublabel for the reasoning-parser override field")) {
                    TextInput(text: vm.bindProfile($vm.reasoningParser),
                              placeholder: "auto", mono: true, width: 150)
                }
            }
            Row(label: String(localized: "settings.advanced.pin_memory.label",
                              defaultValue: "Pin in memory",
                              comment: "Row label for the pin-in-memory toggle"),
                sublabel: String(localized: "settings.advanced.pin_memory.sub",
                                 defaultValue: "Keep this model resident between requests",
                                 comment: "Sublabel for the pin-in-memory toggle")) {
                Toggle("", isOn: vm.bind($vm.isPinned, save: {
                    Task { await vm.save(.isPinned, client: client) }
                }))
                .labelsHidden().toggleStyle(.switch)
            }
            Row(label: String(localized: "settings.advanced.favorite.label",
                              defaultValue: "Favorite",
                              comment: "Row label for the favorite toggle"),
                sublabel: String(localized: "settings.advanced.favorite.sub",
                                 defaultValue: "List this model first in model lists",
                                 comment: "Sublabel for the favorite toggle")) {
                Toggle("", isOn: vm.bind($vm.isFavorite, save: {
                    Task { await vm.save(.isFavorite, client: client) }
                }))
                .labelsHidden().toggleStyle(.switch)
            }
            // Security-sensitive row — flagged red to match the HTML
            // editor's visual treatment. HF custom-code execution gives
            // the model author the ability to run arbitrary Python in
            // the server process; never propagated via profiles             await this.loadOQTasks();
                } catch (err) {
                    console.error('Failed to remove oQ task:', err);
                }
            },

            startOQRefresh() {
                this.stopOQRefresh();
                this._oqRefreshTimer = setInterval(() => {
                    this.loadOQTasks();
                }, 2000);
            },

            stopOQRefresh() {
                if (this._oqRefreshTimer) {
                    clearInterval(this._oqRefreshTimer);
                    this._oqRefreshTimer = null;
                }
            },

            formatOQProgress(task) {
                const pct = Math.round(task.progress || 0);
                const label = task.progress_detail || task.phase || task.status;
                return `${pct}% · ${label}`;
            },

            formatOQElapsed(task) {
                if (!task.started_at) return '';
                const now = task.completed_at || (Date.now() / 1000);
                const elapsed = now - task.started_at;
                const mins = Math.floor(elapsed / 60);
                const secs = Math.floor(elapsed % 60);
                return `${mins}:${String(secs).padStart(2, '0')}`;
            },

            oqSensitivityModelCandidates() {
                if (!this.oqSelectedModelPath) return [];
                const source = this.oqModels.find(m => m.path === this.oqSelectedModelPath);
                if (!source) return [];
                return this.oqAllModels.filter(m =>
                    m.path !== this.oqSelectedModelPath &&
                    m.is_quantized &&
                    m.model_type === source.model_type
                );
            },

            oqMtpAssistantCandidates() {
                // Gemma 4 ships its MTP head as a separate gemma4_assistant
                // checkpoint; offer to merge it into the quantized output.
                // Qwen3.5/3.6 recipients can instead graft the native mtp.*
                // head out of a same-geometry donor checkpoint (e.g. the
                // base model of a fine-tune). Loose filter here; strict
                // tokenizer/geometry validation happens server-side at
                // submit.
                if (!this.oqSelectedModelPath) return [];
                const source = this.oqModels.find(m => m.path === this.oqSelectedModelPath);
                if (!source) return [];
                if (source.model_type === 'gemma4') {
                    return this.oqAllModels.filter(m => m.model_type === 'gemma4_assistant');
                }
                const family = this.oqMtpFamily(source.model_type);
                if (!family) return [];
                if (this.oqSelectedModelHasMtp() && this.oqPreserveMtp) return [];
                return this.oqAllModels.filter(m =>
                    m.path !== source.path &&
                    m.has_mtp_heads &&
                    this.oqMtpFamily(m.model_type) === family &&
                    (!m.hidden_size || !source.hidden_size || m.hidden_size === source.hidden_size)
                );
            },

            oqMtpFamily(modelType) {
                if (!modelType) return null;
                if (modelType.startsWith('qwen3_6')) return 'qwen3_6';
                if (modelType.startsWith('qwen3_5')) return 'qwen3_5';
                return null;
            },

            oqSelectedModelType() {
                const model = this.oqModels.find(m => m.path === this.oqSelectedModelPath);
                return model?.model_type || '';
            },

            oqLevelLabel(level) {
                return `oQ${level}${this.oqEnhanced ? 'e' : ''}`;
            },

            oqSelectedModelIsVLM() {
                const model = this.oqModels.find(m => m.path === this.oqSelectedModelPath);
                return model?.is_vlm || false;
            },

            oqSelectedModelHasMtp() {
                const model = this.oqModels.find(m => m.path === this.oqSelectedModelPath);
                return model?.has_mtp_heads || false;
            },

          up
  constexpr int xs_ld  = group_size + 4;          // padded stride for xs
  constexpr int ws_ld  = group_size + 4;          // padded stride for ws
  constexpr int BM = 32, BN = 32;
  (void)BM; (void)BN;

  // Float32 accumulators: 2×2 SG tile → 4 frags per SG (each covers 8×8 out elements)
  simdgroup_matrix<float, 8, 8> c00, c01, c10, c11;
  c00.thread_elements()[0] = 0.f;  c00.thread_elements()[1] = 0.f;
  c01.thread_elements()[0] = 0.f;  c01.thread_elements()[1] = 0.f;
  c10.thread_elements()[0] = 0.f;  c10.thread_elements()[1] = 0.f;
  c11.thread_elements()[0] = 0.f;  c11.thread_elements()[1] = 0.f;

  const uint sm = sg_id >> 1u;       // SG M-index (0..1)
  const uint sn = sg_id & 1u;        // SG N-index (0..1)
  const uint lane_in_tg = sg_id * 32u + lane;

  // Fragment indices within an 8×8 sub-tile (same derivation as mt_qmm_mma_int2)
  const uint qid = lane >> 2u;
  const uint fm  = (qid & 4u) + ((lane >> 1u) & 3u);    // frag M offset in [0,7]
  const uint fn0 = ((qid & 2u) << 1u) + ((lane & 1u) << 1u);  // frag N offset
  const uint fn1 = fn0 + 1u;

  const uint m_base = tgid.y * (uint)BM;
  const uint n_base = tgid.x * (uint)BN;

  const int M = M_c, N = N_c, K = K_c;
  const int n_groups = K / group_size;

  // Per-block tile-loading assignment
  const uint tl_row     = lane_in_tg >> 2u;    // tile row 0..31 (both X and W)
  const uint tl_sub     = lane_in_tg & 3u;     // K-quarter 0..3
  const uint k_sub_size = (uint)(group_size >> 2);  // BK/4 per sub (32 for gs=128)

  // Precomputed threadgroup-memory read indices for MMA (invariant per K-block)
  const uint xs_m0 = (sm * 16u + fm) * xs_ld;
  const uint xs_m1 = (sm * 16u + 8u + fm) * xs_ld;
  const uint ws_n00 = (sn * 16u       + fn0) * ws_ld;
  const uint ws_n01 = (sn * 16u       + fn1) * ws_ld;
  const uint ws_n10 = (sn * 16u + 8u  + fn0) * ws_ld;
  const uint ws_n11 = (sn * 16u + 8u  + fn1) * ws_ld;

  for (int g = 0; g < n_groups; g++) {
    // ---- Load X tile into xs ----
    {
      const uint m_row = m_base + tl_row;
      const bool m_ok  = m_row < (uint)M;
      const uint k_off = (uint)(g * group_size) + tl_sub * k_sub_size;
      const device T* xp = x + min(m_row, (uint)(M - 1)) * K + k_off;
      const uint xs_dst  = tl_row * xs_ld + tl_sub * k_sub_size;
      for (uint i = 0; i < k_sub_size; i++) {
        xs[xs_dst + i] = m_ok ? xp[i] : T(0);
      }
    }

    // ---- Dequant W tile into ws ----
    {
      const uint n_row  = n_base + tl_row;
      const bool n_ok   = n_row < (uint)N;
      const float sc    = n_ok ? float(scales[n_row * n_groups + g]) : 0.f;
      const uint w_base = n_row * (uint)(n_groups * bpg) + (uint)(g * bpg);
      const uint ks     = tl_sub * k_sub_size;   // K-start within group (0,32,64,96)
      const uint ke     = ks + k_sub_size;        // K-end within group
      const uint b_lo   = ks / 5u;               // first byte index (inclusive)
      const uint b_hi   = (ke - 1u) / 5u;        // last byte index  (inclusive)

      for (uint b = b_lo; b <= b_hi; b++) {
        // Read t5 byte; pad with 1 (neutral trit=1→dq=0) if out of bounds.
        // T5_TO_B4 LUT replaces 4 divmod chains: trit k = (p >> 2k) & 3.
        const uint bval = (n_ok && b < (uint)bpg) ? (uint)w[w_base + b] : 1u;
        const uint p  = T5_TO_B4[bval];
        const uint bk = b * 5u;  // K-index of trit 0 of this byte
        // Write only the trits whose K-position falls in [ks, ke)
        if (bk     >= ks && bk     < ke) ws[tl_row * ws_ld + bk    ] = T(sc * (float( p        & 0x3u) - 1.f));
        if (bk+1u  >= ks && bk+1u  < ke) ws[tl_row * ws_ld + bk+1u ] = T(sc * (float((p >> 2u) & 0x3u) - 1.f));
        if (bk+2u  >= ks && bk+2u  < ke) ws[tl_row * ws_ld + bk+2u ] = T(sc * (float((p >> 4u) & 0x3u) - 1.f));
        if (bk+3u  >= ks && bk+3u  < ke) ws[tl_row * ws_ld + bk+3u ] = T(sc * (float((p >> 6u) & 0x3u) - 1.f));
        if (bk+4u  >= ks && bk+4u  < ke) ws[tl_row * ws_ld + bk+4u ] = T(sc * (float((p >> 8u) & 0x3u) - 1.f));
      }
    }

    threadgroup_barrier(mem_flags::mem_threadgroup);

    // ---- BK/8 simdgroup Mk: {e}"
                        )

        except (_DownloadCancelled, asyncio.CancelledError):
            if task.status not in (
                DownloadStatus.CANCELLED,
                DownloadStatus.FAILED,
            ):
                task.status = DownloadStatus.CANCELLED
            try:
                self._cleanup_partial(task)
            except Exception as e:
                logger.error(
                    f"Failed to clean up cancelled download {task.repo_id}: {e}"
                )
        except RepositoryNotFoundError:
            task.status = DownloadStatus.FAILED
            task.error = (
                f"Repository not found: {task.repo_id}. "
                "This may be a gated model that requires HuggingFace authentication."
            )
            logger.error(f"Repository not found: {task.repo_id}")
        except GatedRepoError:
            task.status = DownloadStatus.FAILED
            task.error = (
                f"Repository '{task.repo_id}' is gated. "
                "Please provide a valid HF token with access."
            )
            logger.error(f"Gated repo access denied: {task.repo_id}")
        except Exception as e:
            # Skip when already cancelled (the xet abort surfaces here as a
            # RuntimeError) or already FAILED by the stall detector, whose
            # error message would otherwise be clobbered by the abort error.
            if (
                task_id not in self._cancelled
                and task.status != DownloadStatus.FAILED
            ):
                task.status = DownloadStatus.FAILED
                task.error = str(e)
                logger.error(f"Download failed for {task.repo_id}: {e}")
        finally:
            # Stop progress polling
            progress_task = self._progress_tasks.pop(task_id, None)
            if progress_task and not progress_task.done():
                progress_task.cancel()

            # Remove from active tasks
            self._active_tasks.pop(task_id, None)

    async def _poll_progress(self, task_id: str, target_dir: Path) -> None:
        """Poll the target directory to estimate download progress.

        Uses both directory size and file modification times to detect
        activity. huggingface_hub pre-allocates large files and fills them
        in, so size alone may not change for extended periods. File mtimes
        are updated on each write syscall and serve as a more reliable
        liveness signal.
        """
        task = self._tasks.get(task_id)
        if task is None:
            return

        last_size = 0
        last_activity_at = time.time()

        try:
            while task.status == DownloadStatus.DOWNLOADING:
                await asyncio.sleep(2)

                if task.status != DownloadStatus.DOWNLOADING:
                    break

                current_size = self._get_dir_size(target_dir)
                task.downloaded_size = current_size

                if task.total_size > 0:
                    # Cap at 99% until snapshot_download confirms completion
                    task.progress = min(
                        (current_size / task.total_size) * 100, 99.0
                    )

                # Activity detection: size change OR file mtime change
                if current_size != last_size:
                    last_size = current_size
                    last_activity_at = time.time()
                else:
                    latest_mtime = self._get_latest_mtime(target_dir)
                    if latest_mtime > last_activity_at:
                        last_activity_at = latest_mtime

                # Stall detection
                if (
                    current_size > 0
                    and (time.time() - last_activity_at) > _STALL_TIMEOUT
                ):
                    task.status = DownloadStatus.FAILED
                    task.error = (
                        f"Download stalled: no progress for {_STALL_TIMEOUT}s. "
                        "Try retrying the download."
                    )
                    logger.warnin.
            Row(label: String(localized: "settings.advanced.trust_remote_code.label",
                              defaultValue: "Trust Remote Code",
                              comment: "Row label for the security-sensitive trust-remote-code toggle"),
                sublabel: String(localized: "settings.advanced.trust_remote_code.sub",
                                 defaultValue: "Execute HuggingFace custom model code. Only enable for models you trust. Per-model only — never inherited from profiles.",
                                 comment: "Sublabel describing the security implications of trust-remote-code"),
                isLast: true) {
                Toggle("", isOn: vm.bind($vm.trustRemoteCode, save: {
                    Task { await vm.save(.trustRemoteCode, client: client) }
                }))
                .labelsHidden().toggleStyle(.switch)
                .tint(theme.redDot)
            }
        }

        SectionHeader(
            String(localized: "settings.advanced.chat_template.section",
                   defaultValue: "Chat Template Kwargs",
                   comment: "Section header above the chat-template kwargs editor"),
            subtitle: String(localized: "settings.advanced.chat_template.subtitle",
                             defaultValue: "Forwarded to the model's chat template. Toggle Force to override per-request values.",
                             comment: "Subtitle for the chat-template kwargs section")
        )
        ChatTemplateKwargsEditor(vm: vm, client: client)

        if !vm.isDiffusionModel {
            SectionHeader(
                String(localized: "settings.acceleration.section",
                       defaultValue: "Acceleration",
                       comment: "Section header above the Acceleration settings group"),
                subtitle: String(localized: "settings.acceleration.subtitle",
                                 defaultValue: "Decoding speedups for models that support them.",
                                 comment: "Subtitle for the Acceleration settings section")
            )
            AccelerationSection(vm: vm, client: client)

            SectionHeader(
                String(localized: "settings.advanced.experimental.section",
                       defaultValue: "Experimental",
                       comment: "Section header above the Experimental settings group"),
                subtitle: String(localized: "settings.advanced.experimental.subtitle",
                                 defaultValue: "Speculative decoding, KV-cache quantization, and other research features.",
                                 comment: "Subtitle for the Experimental settings section")
            )
            ExperimentalSection(vm: vm, client: client)
        }
    }
}

// MARK: - Chat-template kwargs editor

private struct ChatTemplateKwargsEditor: View {
    var vm: ModelSettingsScreenVM
    let client: OMLXClient

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        ListGroup {
            FreeRow {
                HStack {
                    Text(vm.chatTemplateEntries.isEmpty
                         ? String(localized: "settings.advanced.chat_template.empty",
                                  defaultValue: "No chat-template kwargs.",
                                  comment: "Placeholder text shown when no chat-template kwargs are configured")
                         : String(localized: "settings.advanced.chat_template.count",
                                  defaultValue: "kwargs: \(vm.chatTemplateEntries.count)",
                                  comment: "Count summary in the chat-template editor; placeholder is the entry count"))
                        .font(.omlxText(12))
                        .foregroundStyle(theme.textSecondary)
                    Spacer()
                    addMenu
                }
            }
            ForEach(vm.chatTemplateEntries) { entry in
                let isLast = entry.id == vm.chatTemplateEntries.last?.id
                FreeRow(isLast: isLast) {
               oqEstimatedMemory() {
                // Use precise estimate from API if available
                if (this.oqEstimate) {
                    // If sensitivity model selected, memory ≈ sensitivity model size × 1.5
                    if (this.oqSensitivityModelPath) {
                        const sensModel = this.oqAllModels.find(m => m.path === this.oqSensitivityModelPath);
                        if (sensModel) {
                            const bytes = Math.round(sensModel.size * 1.5) + 5 * 1024 * 1024 * 1024;
                            if (bytes > 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024)).toFixed(1) + ' GB';
                            return (bytes / (1024 * 1024)).toFixed(0) + ' MB';
                        }
                    }
                    return this.oqEstimate.memory_streaming_formatted || '';
                }
                // Fallback to rough model-level estimate
                const model = this.oqModels.find(m => m.path === this.oqSelectedModelPath);
                if (!model) return '';
                return model.memory_streaming?.peak_formatted || '';
            },

            oqEstimate: null,
            _oqEstimateTimer: null,

            oqEstimatedBpw() {
                return this.oqEstimate?.effective_bpw?.toFixed(1) || '';
            },

            oqEstimatedOutputSize() {
                return this.oqEstimate?.output_size_formatted || '';
            },

            oqRefreshEstimate() {
                // Debounce: wait 300ms after last change
                if (this._oqEstimateTimer) clearTimeout(this._oqEstimateTimer);
                if (!this.oqSelectedModelPath) {
                    this.oqEstimate = null;
                    return;
                }
                this._oqEstimateTimer = setTimeout(async () => {
                    try {
                        const params = new URLSearchParams({
                            model_path: this.oqSelectedModelPath,
                            oq_level: this.oqLevel,
                            preserve_mtp: this.oqSelectedModelHasMtp() && this.oqPreserveMtp ? 'true' : 'false',
                        });
                        const resp = await fetch(`/admin/api/oq/estimate?${params}`);
                        if (resp.ok) {
                            this.oqEstimate = await resp.json();
                        }
                    } catch (e) {
                        console.error('Failed to estimate oQ:', e);
                    }
                }, 300);
            },

            // =================================================================
            // oQ Uploader Functions
            // =================================================================

            async validateUploadToken() {
                if (!this.uploadHfToken || this.uploadTokenValidating) return;
                this.uploadTokenValidating = true;
                this.uploadError = '';
                try {
                    const response = await fetch('/admin/api/upload/validate-token', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ hf_token: this.uploadHfToken }),
                    });
                    const data = await response.json().catch(() => ({}));
                    if (response.ok) {
                        this.uploadHfUsername = data.username || '';
                        this.uploadHfOrgs = data.orgs || [];
                        this.uploadHfNamespace = this.uploadHfUsername;
                        this.uploadTokenValidated = true;
                        localStorage.setItem('omlx-hf-upload-token', this.uploadHfToken);
                        this.loadUploadOqModels();
                    } else {
                        this.uploadError = data.detail || window.t('models.uploader.invalid_token');
                        this.uploadTokenValidated = false;
                    }
                } catch (err) {
                    this.uploadError = 'Connection MA steps ----
    {
      simdgroup_matrix<T, 8, 8> a0, a1, b0, b1;
      for (uint ki = 0; ki < (uint)(group_size >> 3); ki++) {
        const uint ko = ki * 8u;
        a0.thread_elements()[0] = xs[xs_m0 + fn0 + ko];
        a0.thread_elements()[1] = xs[xs_m0 + fn1 + ko];
        a1.thread_elements()[0] = xs[xs_m1 + fn0 + ko];
        a1.thread_elements()[1] = xs[xs_m1 + fn1 + ko];
        b0.thread_elements()[0] = ws[ws_n00 + fm + ko];
        b0.thread_elements()[1] = ws[ws_n01 + fm + ko];
        b1.thread_elements()[0] = ws[ws_n10 + fm + ko];
        b1.thread_elements()[1] = ws[ws_n11 + fm + ko];
        simdgroup_barrier(mem_flags::mem_none);
        simdgroup_multiply_accumulate(c00, a0, b0, c00);
        simdgroup_multiply_accumulate(c01, a0, b1, c01);
        simdgroup_multiply_accumulate(c10, a1, b0, c10);
        simdgroup_multiply_accumulate(c11, a1, b1, c11);
        simdgroup_barrier(mem_flags::mem_none);
      }
    }

    threadgroup_barrier(mem_flags::mem_threadgroup);
  }

  // ---- Write output ----
  const uint om0  = m_base + sm * 16u + fm;
  const uint om1  = m_base + sm * 16u + 8u + fm;
  const uint on0  = n_base + sn * 16u + fn0;
  const uint on1  = n_base + sn * 16u + fn1;
  const uint on80 = n_base + sn * 16u + 8u + fn0;
  const uint on81 = n_base + sn * 16u + 8u + fn1;

  if (om0 < (uint)M) {
    if (on0  < (uint)N) out[om0 * N + on0 ] = T(c00.thread_elements()[0]);
    if (on1  < (uint)N) out[om0 * N + on1 ] = T(c00.thread_elements()[1]);
    if (on80 < (uint)N) out[om0 * N + on80] = T(c01.thread_elements()[0]);
    if (on81 < (uint)N) out[om0 * N + on81] = T(c01.thread_elements()[1]);
  }
  if (om1 < (uint)M) {
    if (on0  < (uint)N) out[om1 * N + on0 ] = T(c10.thread_elements()[0]);
    if (on1  < (uint)N) out[om1 * N + on1 ] = T(c10.thread_elements()[1]);
    if (on80 < (uint)N) out[om1 * N + on80] = T(c11.thread_elements()[0]);
    if (on81 < (uint)N) out[om1 * N + on81] = T(c11.thread_elements()[1]);
  }
}

template <typename T, const int group_size, const int bits>
METAL_FUNC void qvm_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    const int in_vec_size,
    const int out_vec_size,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  constexpr int power_of_2_bits = (bits & (bits - 1)) == 0;
  constexpr int num_simdgroups = 2;
  constexpr int pack_factor = get_pack_factor<bits, 32>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();

  constexpr int tn = 32 / pack_factor;
  constexpr int block_size = SIMD_SIZE;

  using W_T =
      typename ConditionalType<power_of_2_bits, uint32_t, uint8_t>::type;
  const device W_T* ws = (const device W_T*)w;

  typedef float U;
  typedef struct {
    W_T wi[tn * bytes_per_pack];
  } vec_w;

  thread vec_w w_local;
  thread U result[tn * pack_factor] = {0};
  thread U scale = 1;
  thread U bias = 0;
  thread U x_local = 0;

  // Adjust positions
  const int out_vec_size_w = out_vec_size * bytes_per_pack / pack_factor;
  const int out_vec_size_g = out_vec_size / group_size;
  int out_col = pack_factor * tn * (tid.y * num_simdgroups + simd_gid);
  ws += out_col * bytes_per_pack / pack_factor + simd_lid * out_vec_size_w;
  scales += out_col / group_size + simd_lid * out_vec_size_g;
  biases += out_col / group_size + simd_lid * out_vec_size_g;
  x += tid.x * in_vec_size + simd_lid;
  y += tid.x * out_vec_size + out_col;

  if (out_col >= out_vec_size) {
    return;
  }

  // Loop over in_vec in blocks of block_size
  int remaining = in_vec_size % block_size;
  if (remaining == 0) {
    for (int i = 0; i < in_vec_size; i += block_size) {
      x_local = *x;
      scale = *scales;
      bias = *biases;
      w_local = *((device vec_w*)ws);
      qouter<U, tn * pack_factor, bits>(
          (thread uint8_t*)&w_local, x_local, scale, bias, result);

      x += block_size;
      scales += block_size * out_vec_size_g;
      biases += block_size * out_vec_size_g;g(
                        f"Download stalled for {task.repo_id} "
                        f"(task_id={task_id})"
                    )
                    # Cancel the snapshot_download thread. The task cancel
                    # only unblocks the awaiting coroutine; aborting the xet
                    # session is what actually reaps a wedged transfer thread.
                    active_task = self._active_tasks.get(task_id)
                    if active_task and not active_task.done():
                        active_task.cancel()
                    abort_xet_session()
                    break
        except asyncio.CancelledError:
            pass

    @staticmethod
    def _get_latest_mtime(path: Path) -> float:
        """Return the most recent modification time of any file in a directory."""
        if not path.exists():
            return 0.0
        latest = 0.0
        try:
            for f in path.rglob("*"):
                if f.is_file():
                    try:
                        mt = f.stat().st_mtime
                        if mt > latest:
                            latest = mt
                    except OSError:
                        pass
        except OSError:
            pass
        return latest

    @staticmethod
    def _get_dir_size(path: Path) -> int:
        """Calculate total size of all files in a directory."""
        if not path.exists():
            return 0
        total = 0
        try:
            for f in path.rglob("*"):
                if f.is_file():
                    try:
                        total += f.stat().st_size
                    except OSError:
                        pass
        except OSError:
            pass
        return total

    def _cleanup_partial(self, task: DownloadTask) -> None:
        """Remove in-progress shards while keeping finalized files for resume.

        Hub stages partial downloads inside a hidden ``._____temp`` directory
        and only renames a shard into the target on completion. Wiping the
        whole target dir would also nuke shards the user has already paid
        for; finalized files are visible in the file browser, so users can
        keep them for auto-resume on retry or remove them themselves.
        """
        target_dir = self._model_dir / task.repo_id
        temp_dir = target_dir / "._____temp"
        if temp_dir.exists():
            try:
                shutil.rmtree(temp_dir)
                logger.info(f"Cleaned up in-progress shards: {temp_dir}")
            except Exception as e:
                logger.error(f"Failed to clean up {temp_dir}: {e}")


# ===== FILE: omlx/admin/hf_uploader.py =====

# SPDX-License-Identifier: Apache-2.0
"""HuggingFace model uploader for oMLX admin panel.

Uploads oQ-quantized models to HuggingFace Hub with queue-based sequential
processing, following the same pattern as hf_downloader.py.
"""

import asyncio
import enum
import json
import logging
import shutil
import tempfile
import time
import uuid
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional

logger = logging.getLogger(__name__)


def _format_size(size_bytes: int) -> str:
    """Format size in bytes to human-readable string."""
    if size_bytes < 1024**2:
        return f"{size_bytes / 1024:.1f} KB"
    elif size_bytes < 1024**3:
        return f"{size_bytes / 1024**2:.1f} MB"
    else:
        return f"{size_bytes / 1024**3:.1f} GB"


def _has_meaningful_readme(path: Path) -> bool:
    """Check if a README.md exists and has content beyond YAML frontmatter.

    Returns False if the file doesn't exist, is empty, or contains only
    YAML frontmatter (e.g. mlx-lm's default stub).
    """
    readme = path / "README.md"
    if not readme.exists():
        return False
    try:
        text = readme.read_text(encoding="utf-8").strip()
    except Exception:
        return False
    if not text:
        return False
    # Strip YAML frontmatter and check if anything remains
    if text.startswith("---"):
        parts = text.split("---", 2)
        # parts[0] is empty (before       EntryEditor(
                        vm: vm,
                        client: client,
                        entryID: entry.id
                    )
                }
            }
        }
    }

    @ViewBuilder
    private var addMenu: some View {
        Menu {
            // `enable_thinking` and `reasoning_effort` are server-side
            // singletons — once added, the menu hides them so the user
            // can't push duplicate keys into `chat_template_kwargs`.
            if !vm.isDiffusionModel,
               !vm.chatTemplateEntries.contains(where: { $0.kind == .enableThinking }) {
                Button("enable_thinking") {
                    vm.addKwarg(.enableThinking)
                }
            }
            if !vm.isDiffusionModel,
               !vm.chatTemplateEntries.contains(where: { $0.kind == .reasoningEffort }) {
                Button("reasoning_effort") {
                    vm.addKwarg(.reasoningEffort)
                }
            }
            Button(String(localized: "settings.advanced.chat_template.add_custom",
                          defaultValue: "custom…",
                          comment: "Menu item for adding a custom (free-form key/value) chat-template kwarg")) {
                vm.addKwarg(.custom)
            }
        } label: {
            Label(String(localized: "settings.advanced.chat_template.add_kwarg",
                         defaultValue: "Add kwarg",
                         comment: "Plus-button label for adding a chat-template kwarg row"),
                  systemImage: "plus")
                .labelStyle(.titleAndIcon)
        }
        .menuStyle(.borderlessButton)
        .fixedSize()
    }
}

private struct EntryEditor: View {
    var vm: ModelSettingsScreenVM
    let client: OMLXClient
    let entryID: UUID

    @Environment(\.omlxTheme) private var theme

    private var entry: ChatTemplateKwargEntry {
        vm.chatTemplateEntries.first { $0.id == entryID } ?? ChatTemplateKwargEntry(kind: .custom, value: "")
    }

    private var binding: Binding<ChatTemplateKwargEntry> {
        Binding(
            get: { vm.chatTemplateEntries.first { $0.id == entryID } ?? ChatTemplateKwargEntry(kind: .custom, value: "") },
            set: { newValue in
                if let idx = vm.chatTemplateEntries.firstIndex(where: { $0.id == entryID }) {
                    vm.chatTemplateEntries[idx] = newValue
                }
            }
        )
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 6) {
            HStack(spacing: 8) {
                Text(typeLabel)
                    .font(.omlxText(11, weight: .semibold))
                    .foregroundStyle(theme.textSecondary)
                Spacer()
                Button {
                    vm.removeKwarg(id: entryID)
                } label: {
                    Image(systemName: "xmark")
                        .font(.system(size: 11, weight: .medium))
                        .foregroundStyle(theme.textSecondary)
                        .frame(width: 22, height: 22)
                        .contentShape(Rectangle())
                }
                .buttonStyle(.plain)
                .help(String(localized: "settings.advanced.chat_template.remove",
                             defaultValue: "Remove kwarg",
                             comment: "Tooltip on the trash/xmark button that deletes a chat-template kwarg row"))
            }
            valueRow
        }
    }

    private var typeLabel: String {
        // These are eyebrow labels rendered uppercase above each editor.
        // Keeping the localization keys aligned with display text rather
        // than the server kwarg key.
        switch entry.kind {
        case .enableThinking:
            return String(localized: "settings.advanced.chat_template.type.enable_thinking",
                          defaultValue: "ENABLE_THINKING",
                          comment: "Eyebrow label above the enable_thinking kwarg editor")
        case .reasoningEffort:
            return String(localized: "settings.advancerror. Server may be unavailable.';
                } finally {
                    this.uploadTokenValidating = false;
                }
            },

            async loadUploadOqModels() {
                try {
                    const response = await fetch('/admin/api/upload/oq-models');
                    if (response.ok) {
                        const data = await response.json();
                        this.uploadOqModels = data.oq_models || [];
                        this.uploadAllModels = data.all_models || [];
                        this.uploadOqModelsLoaded = true;
                    }
                } catch (err) {
                    console.error('Failed to load oQ models for upload:', err);
                }
            },

            openUploadModal(model) {
                this.uploadModalModelPath = model.path;
                this.uploadModalModelName = model.name;
                this.uploadModalRepoId = (this.uploadHfNamespace || this.uploadHfUsername) + '/' + model.name;
                this.uploadReadmeSource = '';
                this.uploadAutoReadme = true;
                this.uploadRedownloadNotice = false;
                this.uploadPrivate = false;
                this.uploadStarting = false;
                this.uploadModalOpen = true;
            },

            async startUpload() {
                if (!this.uploadModalRepoId || this.uploadStarting) return;
                this.uploadStarting = true;
                this.uploadError = '';
                try {
                    const response = await fetch('/admin/api/upload/start', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            model_path: this.uploadModalModelPath,
                            repo_id: this.uploadModalRepoId,
                            hf_token: this.uploadHfToken,
                            readme_source_path: this.uploadReadmeSource,
                            auto_readme: this.uploadAutoReadme,
                            redownload_notice: this.uploadRedownloadNotice && this.uploadReadmeSource === '',
                            private: this.uploadPrivate,
                        }),
                    });
                    const data = await response.json().catch(() => ({}));
                    if (response.ok) {
                        this.uploadModalOpen = false;
                        this.uploadSuccess = `Upload queued: ${this.uploadModalModelName}`;
                        await this.loadUploadTasks();
                        this.startUploadRefresh();
                        setTimeout(() => { this.uploadSuccess = ''; }, 5000);
                    } else {
                        this.uploadError = data.detail || 'Failed to start upload';
                    }
                } catch (err) {
                    this.uploadError = 'Connection error. Server may be unavailable.';
                } finally {
                    this.uploadStarting = false;
                }
            },

            async loadUploadTasks() {
                try {
                    const response = await fetch('/admin/api/upload/tasks');
                    if (response.ok) {
                        const data = await response.json();
                        this.uploadTasks = data.tasks || [];
                        const hasActive = this.uploadTasks.some(t =>
                            ['pending', 'uploading'].includes(t.status));
                        if (!hasActive) {
                            this.stopUploadRefresh();
                        }
                    }
                } catch (err) {
                    console.error('Failed to load upload tasks:', err);
                }
            },

            async cancelUploadTask(taskId) {
                try {
                    await fetch(`/admin/api/upload/cancel/${taskId}`, { method: 'POST' });
                    await this.loadUploadTasks();
                } catch (err) {

      ws += block_size * out_vec_size_w;
    }
  } else {
    for (int i = block_size; i < in_vec_size; i += block_size) {
      x_local = *x;
      scale = *scales;
      bias = *biases;
      w_local = *((device vec_w*)ws);

      qouter<U, tn * pack_factor, bits>(
          (thread uint8_t*)&w_local, x_local, scale, bias, result);

      x += block_size;
      scales += block_size * out_vec_size_g;
      biases += block_size * out_vec_size_g;
      ws += block_size * out_vec_size_w;
    }
    if (static_cast<int>(simd_lid) < remaining) {
      x_local = *x;
      scale = *scales;
      bias = *biases;
      w_local = *((device vec_w*)ws);
    } else {
      x_local = 0;
      scale = 0;
      bias = 0;
    }
    qouter<U, tn * pack_factor, bits>(
        (thread uint8_t*)&w_local, x_local, scale, bias, result);
  }

// Accumulate in the simdgroup
#pragma clang loop unroll(full)
  for (int k = 0; k < tn * pack_factor; k++) {
    result[k] = simd_sum(result[k]);
  }

  // Store the result
  if (simd_lid == 0) {
#pragma clang loop unroll(full)
    for (int k = 0; k < tn * pack_factor; k++) {
      y[k] = static_cast<T>(result[k]);
    }
  }
}

template <
    typename T,
    const int group_size,
    const int bits,
    const bool aligned_N,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
METAL_FUNC void qmm_t_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    threadgroup T* Xs,
    threadgroup T* Ws,
    const constant int& K,
    const constant int& N,
    const constant int& M,
    const constant int& K_eff,
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  static_assert(BK >= SIMD_SIZE, "BK should be larger than SIMD_SIZE");
  static_assert(BK % SIMD_SIZE == 0, "BK should be divisible by SIMD_SIZE");

  (void)lid;

  constexpr int WM = 2;
  constexpr int WN = 2;
  constexpr int pack_factor = get_pack_factor<bits, 8>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();

  constexpr int BK_padded = (BK + 16 / sizeof(T));

  // Instantiate the appropriate BlockMMA and Loader
  using mma_t = mlx::steel::
      BlockMMA<T, T, BM, BN, BK, WM, WN, false, true, BK_padded, BK_padded>;
  using loader_x_t =
      mlx::steel::BlockLoader<T, BM, BK, BK_padded, 1, WM * WN * SIMD_SIZE>;
  using loader_w_t = QuantizedBlockLoader<
      T,
      BN,
      BK,
      BK_padded,
      1,
      WM * WN * SIMD_SIZE,
      group_size,
      bits>;

  // Set the block
  const int K_w = K * bytes_per_pack / pack_factor;
  const int K_g = K / group_size;
  const int y_row = tid.y * BM;
  const int y_col = tid.x * BN;

  auto wl = (const device uint8_t*)w;

  x += y_row * static_cast<int64_t>(K);
  wl += y_col * K_w;
  scales += y_col * K_g;
  biases += y_col * K_g;
  y += y_row * static_cast<int64_t>(N) + y_col;

  // Make the x loader and mma operation
  const short num_els = min(BM, M - y_row);
  const short num_outs = min(BN, N - y_col);
  loader_x_t loader_x(x, K, Xs, simd_gid, simd_lid);
  loader_w_t loader_w(wl, scales, biases, K, Ws, simd_gid, simd_lid);
  mma_t mma_op(simd_gid, simd_lid);

  if (num_els < BM) {
    if (!aligned_N && num_outs < BN) {
      for (int k = 0; k < K_eff; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_safe(short2(BK, num_els));
        loader_w.load_safe(short2(BK, num_outs));
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    } else {
      for (int k = 0; k < K_eff; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_safe(short2(BK, num_els));
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    }
  } else {
    if (!aligned_N && num_outs < BN) { first ---), parts[1] is frontmatter
        if len(parts) >= 3:
            body = parts[2].strip()
            return len(body) > 0
        # Only opening --- or unclosed frontmatter
        return False
    return True


def _is_oq_model(name: str) -> bool:
    """Check if a model name indicates an oQ-quantized model.

    Any folder name containing 'oQ' (case-sensitive) is treated as an oQ model,
    e.g. 'Qwen3.5-122B-oQ4', 'Llama-3B-oQ4e', 'Qwen3.6-27B-oQ3.5e'.
    """
    return "oQ" in name


def _generate_model_card(
    model_name: str, config: dict, redownload_notice: bool = False,
) -> str:
    """Generate a minimal HuggingFace model card for an oQ model."""
    from omlx._version import __version__

    model_type = config.get("model_type", "unknown")
    quant = config.get("quantization", {})
    bits = quant.get("bits", "?")
    group_size = quant.get("group_size", "?")

    notice = ""
    if redownload_notice:
        from datetime import date

        today = date.today().strftime("%Y-%m-%d")
        notice = f"""> [!IMPORTANT]
> This quantization was uploaded on **{today}** and replaces a previous version.
> If you downloaded this model before this date, please re-download for the updated weights.

"""

    return f"""---
library_name: mlx
tags:
- mlx
- oq
- quantized
---

{notice}# {model_name}

This model was quantized using [oQ](https://github.com/jundot/omlx) (oMLX v{__version__}) mixed-precision quantization.

## Quantization details

- **Model type**: {model_type}
- **Bits**: {bits}
- **Group size**: {group_size}
- **Format**: MLX safetensors
"""


class UploadStatus(str, enum.Enum):
    """Status of an upload task."""

    PENDING = "pending"
    UPLOADING = "uploading"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


_ACTIVE_STATUSES = {UploadStatus.PENDING, UploadStatus.UPLOADING}


@dataclass
class UploadTask:
    """Represents a single model upload task."""

    task_id: str
    model_name: str
    model_path: str
    repo_id: str
    status: UploadStatus = UploadStatus.PENDING
    progress: float = 0.0
    error: str = ""
    created_at: float = field(default_factory=time.time)
    started_at: float = 0.0
    completed_at: float = 0.0
    total_size: int = 0
    repo_url: str = ""

    def to_dict(self) -> dict:
        """Serialize task to a JSON-compatible dict."""
        return {
            "task_id": self.task_id,
            "model_name": self.model_name,
            "model_path": self.model_path,
            "repo_id": self.repo_id,
            "status": self.status.value,
            "progress": round(self.progress, 1),
            "error": self.error,
            "created_at": self.created_at,
            "started_at": self.started_at,
            "completed_at": self.completed_at,
            "total_size": self.total_size,
            "total_size_formatted": _format_size(self.total_size) if self.total_size else "",
            "repo_url": self.repo_url,
        }


class HFUploader:
    """Manages HuggingFace model uploads with queue-based sequential processing.

    Uses huggingface_hub's upload_folder() with a semaphore to ensure only
    one upload runs at a time. Multiple uploads can be queued.

    Args:
        model_dirs: List of model directory paths to scan for oQ models.
    """

    def __init__(self, model_dirs: list[str]):
        self._model_dirs = [Path(d) for d in model_dirs]
        self._tasks: dict[str, UploadTask] = {}
        self._active_tasks: dict[str, asyncio.Task] = {}
        self._cancelled: set[str] = set()
        self._upload_sem = asyncio.Semaphore(1)

    def update_model_dirs(self, model_dirs: list[str]) -> None:
        """Update model directory paths."""
        self._model_dirs = [Path(d) for d in model_dirs]

    @staticmethod
    async def validate_token(token: str) -> dict:
        """Validate a HuggingFace token and return user info.

        Args:
            token: HuggingFace write-access token.

        Returns:
            Dict with 'username' and 'orgs' list.

        Raises:
            ValueError: If ed.chat_template.type.reasoning_effort",
                          defaultValue: "REASONING_EFFORT",
                          comment: "Eyebrow label above the reasoning_effort kwarg editor")
        case .custom:
            return String(localized: "settings.advanced.chat_template.type.custom",
                          defaultValue: "CUSTOM",
                          comment: "Eyebrow label above a custom (free-form) chat-template kwarg editor")
        }
    }

    @ViewBuilder
    private var valueRow: some View {
        switch entry.kind {
        case .enableThinking:
            HStack(spacing: 8) {
                Popup(
                    selection: vm.bindProfile(binding.value),
                    width: 130,
                    options: [("true", "true"), ("false", "false")]
                )
                forceCheckbox
            }
        case .reasoningEffort:
            HStack(spacing: 8) {
                Popup(
                    selection: vm.bindProfile(binding.value),
                    width: 130,
                    options: [
                        ("low", "low"),
                        ("medium", "medium"),
                        ("high", "high"),
                        ("max", "max"),
                    ]
                )
                forceCheckbox
            }
        case .custom:
            VStack(alignment: .leading, spacing: 6) {
                TextInput(text: vm.bindProfile(binding.customKey),
                          placeholder: String(localized: "settings.advanced.chat_template.key_placeholder",
                                              defaultValue: "key",
                                              comment: "Placeholder for the custom kwarg key field"),
                          mono: true)
                HStack(spacing: 8) {
                    TextInput(text: vm.bindProfile(binding.value),
                              placeholder: String(localized: "settings.advanced.chat_template.value_placeholder",
                                                  defaultValue: "value",
                                                  comment: "Placeholder for the custom kwarg value field"),
                              mono: true)
                    forceCheckbox
                }
            }
        }
    }

    private var forceCheckbox: some View {
        Toggle(isOn: vm.bindProfile(binding.force)) {
            Text(String(localized: "settings.advanced.chat_template.force",
                        defaultValue: "Force",
                        comment: "Checkbox label for forcing a chat-template kwarg via forced_ct_kwargs"))
                .font(.omlxText(11))
                .foregroundStyle(theme.textSecondary)
        }
        .toggleStyle(.checkbox)
        .help(String(localized: "settings.advanced.chat_template.force.help",
                     defaultValue: "Add this key to forced_ct_kwargs so the request body can't override it.",
                     comment: "Tooltip explaining the Force checkbox"))
    }
}

// MARK: - Acceleration section

private struct AccelerationSection: View {
    @Bindable var vm: ModelSettingsScreenVM
    let client: OMLXClient

    var body: some View {
        // Profile-eligible like the experimental fields below — edits
        // write to the working profile via bindProfile.
        ListGroup {
            // Lightning MTP
            Row(label: String(localized: "settings.acceleration.mtp.label",
                              defaultValue: "Lightning MTP",
                              comment: "Row label for the Lightning MTP toggle"),
                sublabel: mtpSublabel,
                isLast: true) {
                Toggle("", isOn: vm.bindProfile($vm.mtpEnabled))
                    .labelsHidden().toggleStyle(.switch)
                    .disabled(mtpToggleDisabled)
                    .help(vm.mtpConflictReason ?? vm.model?.mtpCompatibilityReason ?? "")
            }
        }
    }

    private var mtpToggleDisabled: Bool {
        let compatible = vm.model?.mtpCompatible ?? true
        if !compatible &    console.error('Failed to cancel upload task:', err);
                }
            },

            async removeUploadTask(taskId) {
                try {
                    await fetch(`/admin/api/upload/task/${taskId}`, { method: 'DELETE' });
                    await this.loadUploadTasks();
                } catch (err) {
                    console.error('Failed to remove upload task:', err);
                }
            },

            startUploadRefresh() {
                this.stopUploadRefresh();
                this._uploadRefreshTimer = setInterval(() => {
                    this.loadUploadTasks();
                }, 2000);
            },

            stopUploadRefresh() {
                if (this._uploadRefreshTimer) {
                    clearInterval(this._uploadRefreshTimer);
                    this._uploadRefreshTimer = null;
                }
            },

            formatUploadElapsed(task) {
                if (!task.started_at) return '';
                const now = task.completed_at || (Date.now() / 1000);
                const elapsed = now - task.started_at;
                const mins = Math.floor(elapsed / 60);
                const secs = Math.floor(elapsed % 60);
                return `${mins}:${String(secs).padStart(2, '0')}`;
            },

            // =================================================================
            // Recommended Models Functions
            // =================================================================

            async loadRecommendedModels() {
                this.hfRecommendedLoading = true;
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 15000);
                try {
                    const response = await fetch(`/admin/api/hf/recommended?mlx_only=${this.hfMlxOnly}`, { signal: controller.signal });
                    if (response.ok) {
                        const data = await response.json();
                        this.hfTokenInvalid = !!data.hf_token_invalid;
                        // Attach original rank so the # column survives column-header re-sorts
                        this.hfRecommended = {
                            trending: (data.trending || []).map((m, i) => ({ ...m, rank: i + 1 })),
                            popular: (data.popular || []).map((m, i) => ({ ...m, rank: i + 1 })),
                        };
                        this.hfRecommendedLoaded = true;
                        this.hfPage.trending = 1;
                        this.hfPage.popular = 1;
                        // Default sort for trending/popular is original rank
                        this.hfTableSort = 'rank';
                        this.hfTableSortDir = 'asc';
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.hfError = data.detail || 'Failed to load recommended models';
                        setTimeout(() => { this.hfError = ''; }, 5000);
                    }
                } catch (err) {
                    if (err.name === 'AbortError') {
                        this.hfError = 'HuggingFace request timed out. The service may be unavailable.';
                    } else {
                        this.hfError = 'Failed to connect to HuggingFace.';
                    }
                    setTimeout(() => { this.hfError = ''; }, 5000);
                    console.error('Failed to load recommended models:', err);
                } finally {
                    clearTimeout(timeoutId);
                    this.hfRecommendedLoading = false;
                }
            },

            downloadRecommended(repoId) {
                this.hfRepoId = repoId;
                this.startHFDownload();
            },

            getMemoryFitStatus(sizeBytes) {
                const totalBytes = this.globalSettings.system?.total_memory_bytes || 0;
                if (
      for (int k = 0; k < K_eff; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_unsafe();
        loader_w.load_safe(short2(BK, num_outs));
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    } else {
      for (int k = 0; k < K_eff; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_unsafe();
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);

        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    }
  }

  // Store results to device memory
  threadgroup_barrier(mem_flags::mem_threadgroup);
  if (num_els < BM || num_outs < BN) {
    mma_op.store_result_safe(y, N, short2(num_outs, num_els));
  } else {
    mma_op.store_result(y, N);
  }
}

template <
    typename T,
    const int group_size,
    const int bits,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
METAL_FUNC void qmm_n_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    threadgroup T* Xs,
    threadgroup T* Ws,
    const constant int& K,
    const constant int& N,
    const constant int& M,
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  static_assert(BK >= SIMD_SIZE, "BK should be larger than SIMD_SIZE");
  static_assert(BK % SIMD_SIZE == 0, "BK should be divisible by SIMD_SIZE");

  (void)lid;

  constexpr int WM = 2;
  constexpr int WN = 2;
  constexpr int pack_factor = get_pack_factor<bits, 8>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();

  constexpr int BK_padded = (BK + 16 / sizeof(T));
  constexpr int BN_padded = (BN + 16 / sizeof(T));

  // Instantiate the appropriate BlockMMA and Loader
  using mma_t = mlx::steel::
      BlockMMA<T, T, BM, BN, BK, WM, WN, false, false, BK_padded, BN_padded>;
  using loader_x_t = mlx::steel::
      BlockLoader<T, BM, BK, BK_padded, 1, WM * WN * SIMD_SIZE, 1, 4>;
  using loader_w_t = QuantizedBlockLoader<
      T,
      BK,
      BN,
      BN_padded,
      0,
      WM * WN * SIMD_SIZE,
      group_size,
      bits>;

  auto wl = (const device uint8_t*)w;

  // Set the block
  const int y_row = tid.y * BM;
  const int y_col = tid.x * BN;
  x += y_row * static_cast<int64_t>(K);
  wl += y_col * bytes_per_pack / pack_factor;
  scales += y_col / group_size;
  biases += y_col / group_size;
  y += y_row * static_cast<int64_t>(N) + y_col;

  // Make the x loader and mma operation
  const short num_els = min(BM, M - y_row);
  loader_x_t loader_x(x, K, Xs, simd_gid, simd_lid);
  loader_w_t loader_w(wl, scales, biases, N, Ws, simd_gid, simd_lid);
  mma_t mma_op(simd_gid, simd_lid);

  if (num_els < BM) {
    if ((K % BK) != 0) {
      const int k_blocks = K / BK;
      for (int k = 0; k < k_blocks; k++) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_safe(short2(BK, num_els));
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
      const short num_k = K - k_blocks * BK;
      threadgroup_barrier(mem_flags::mem_threadgroup);
      loader_x.load_safe(short2(num_k, num_els));
      loader_w.load_safe(short2(BN, num_k));
      threadgroup_barrier(mem_flags::mem_threadgroup);
      mma_op.mma(Xs, Ws);
    } else {
      for (int k = 0; k < K; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_safe(short2(BK, num_els));
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    }
  } else {
    if ((K % BK) != 0) {
      const int k_blocks = K / BK;
      for (int k = 0; k < k_blocks; k++) {
        threadgrothe token is invalid or lacks write access.
        """
        from huggingface_hub import HfApi

        try:
            api = HfApi()
            info = await asyncio.to_thread(api.whoami, token=token)
        except Exception as e:
            raise ValueError(f"Invalid token: {e}")

        username = info.get("name", "")
        orgs = [
            {"name": org.get("name", "")}
            for org in info.get("orgs", [])
            if org.get("name")
        ]

        # Check for write access
        auth = info.get("auth", {})
        access_token = auth.get("accessToken", {})
        role = access_token.get("role", "")
        if role == "read":
            raise ValueError(
                "Token has read-only access. A write token is required for uploads."
            )

        return {"username": username, "orgs": orgs}

    async def list_oq_models(self) -> list[dict]:
        """Scan model directories and return oQ-quantized models.

        Returns:
            List of dicts with model name, path, size info.
        """

        def _scan() -> list[dict]:
            models = []
            seen: set[str] = set()

            for model_dir in self._model_dirs:
                if not model_dir.exists():
                    continue
                for subdir in sorted(model_dir.iterdir()):
                    if not subdir.is_dir():
                        continue
                    candidates = []
                    if (subdir / "config.json").exists():
                        candidates.append(subdir)
                    else:
                        for child in sorted(subdir.iterdir()):
                            if child.is_dir() and (child / "config.json").exists():
                                candidates.append(child)

                    for path in candidates:
                        if path.name in seen:
                            continue
                        seen.add(path.name)
                        if not _is_oq_model(path.name):
                            continue
                        try:
                            size = sum(
                                f.stat().st_size
                                for f in path.glob("*.safetensors")
                            )
                            if size == 0:
                                continue
                            models.append({
                                "name": path.name,
                                "path": str(path),
                                "size": size,
                                "size_formatted": _format_size(size),
                            })
                        except Exception:
                            continue
            return models

        return await asyncio.to_thread(_scan)

    async def list_all_models(self) -> list[dict]:
        """Scan model directories and return all models (for README source selection).

        Returns:
            List of dicts with model name and path.
        """

        def _scan() -> list[dict]:
            models = []
            seen: set[str] = set()

            for model_dir in self._model_dirs:
                if not model_dir.exists():
                    continue
                for subdir in sorted(model_dir.iterdir()):
                    if not subdir.is_dir():
                        continue
                    candidates = []
                    if (subdir / "config.json").exists():
                        candidates.append(subdir)
                    else:
                        for child in sorted(subdir.iterdir()):
                            if child.is_dir() and (child / "config.json").exists():
                                candidates.append(child)

                    for path in candidates:
                        if path.name in seen:
                            continue
                        seen.add(path.name)
                        has_readme = _has_meaningful_readme(path)
                        models.append({
                            "name": path.name,
                            "path": & !vm.mtpEnabled { return true }
        if vm.mtpConflictReason != nil { return true }
        return false
    }

    private var mtpSublabel: String {
        if let reason = vm.mtpConflictReason { return reason }
        if let reason = vm.model?.mtpCompatibilityReason,
           !(vm.model?.mtpCompatible ?? true) {
            return reason
        }
        return String(localized: "settings.acceleration.mtp.sub",
                      defaultValue: "Drafts several tokens per step with the model's built-in MTP head. Up to ~1.5x faster decoding for supported models.",
                      comment: "Default sublabel for the Lightning MTP toggle")
    }
}

// MARK: - Experimental section

private struct ExperimentalSection: View {
    @Bindable var vm: ModelSettingsScreenVM
    let client: OMLXClient

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        // All experimental fields are profile-eligible (universal or
        // model-specific). Edits write to the working profile via
        // bindProfile and surface in the Active banner above.
        ListGroup {
            // TurboQuant KV
            Row(label: String(localized: "settings.experimental.turboquant.label",
                              defaultValue: "TurboQuant KV Cache",
                              comment: "Row label for the TurboQuant KV cache toggle"),
                sublabel: turboquantSublabel) {
                HStack(spacing: 8) {
                    if vm.turboquantKvEnabled {
                        Popup(
                            selection: vm.bindProfile($vm.turboquantKvBits),
                            width: 120,
                            options: ModelSettingsScreenVM.turboquantKvBitsOptions
                        )
                    }
                    Toggle("", isOn: vm.bindProfile($vm.turboquantKvEnabled))
                        .labelsHidden().toggleStyle(.switch)
                        .disabled(vm.vlmMtpEnabled)
                        .help(vm.vlmMtpEnabled ? vlmMtpOwnsSpeculativePathReason : "")
                }
            }

            // IndexCache (DSA-only — surface to the user that the row
            // only applies to models whose config matches the DSA set).
            if vm.isDSAConfigModel {
                Row(label: String(localized: "settings.experimental.indexcache.label",
                                  defaultValue: "IndexCache",
                                  comment: "Row label for the DSA IndexCache toggle"),
                    sublabel: String(localized: "settings.experimental.indexcache.sub",
                                     defaultValue: "Sparse attention index cache for DSA models. THUDM/IndexCache.",
                                     comment: "Sublabel describing the DSA IndexCache feature")) {
                    HStack(spacing: 8) {
                        if vm.indexCacheEnabled {
                            TextInput(text: vm.bindProfile($vm.indexCacheFreq),
                                      placeholder: "4", mono: true, width: 80)
                        }
                        Toggle("", isOn: vm.bindProfile($vm.indexCacheEnabled))
                            .labelsHidden().toggleStyle(.switch)
                    }
                }
            }

            // SpecPrefill
            Row(label: String(localized: "settings.experimental.specprefill.label",
                              defaultValue: "SpecPrefill",
                              comment: "Row label for the SpecPrefill toggle"),
                sublabel: specprefillSublabel) {
                Toggle("", isOn: vm.bindProfile($vm.specprefillEnabled))
                    .labelsHidden().toggleStyle(.switch)
                    .disabled(vm.vlmMtpEnabled)
                    .help(vm.vlmMtpEnabled ? vlmMtpOwnsSpeculativePathReason : "")
            }
            if vm.specprefillEnabled {
                Row(label: String(localized: "settings.experimental.specprefill.draft.label",
                                  defaultValue: "Draft Model",
                          !totalBytes || !sizeBytes) return 'safe';
                const ratio = sizeBytes / totalBytes;
                if (ratio > 0.95) return 'danger';
                if (ratio > 0.80) return 'warning';
                return 'safe';
            },

            formatDownloads(count) {
                if (count >= 1000000) return (count / 1000000).toFixed(1) + 'M';
                if (count >= 1000) return (count / 1000).toFixed(1) + 'K';
                return count.toString();
            },

            // Table sort helpers for Browse Models
            sortModels(list) {
                const sortBy = this.hfTableSort;
                const dir = this.hfTableSortDir === 'asc' ? 1 : -1;
                return [...list].sort((a, b) => {
                    if (sortBy === 'rank') {
                        return dir * ((a.rank || 0) - (b.rank || 0));
                    } else if (sortBy === 'name') {
                        return dir * (a.name || '').localeCompare(b.name || '');
                    } else if (sortBy === 'downloads') {
                        return dir * ((a.downloads || 0) - (b.downloads || 0));
                    } else if (sortBy === 'likes') {
                        return dir * ((a.likes || 0) - (b.likes || 0));
                    } else if (sortBy === 'size') {
                        return dir * ((a.size || 0) - (b.size || 0));
                    } else if (sortBy === 'params') {
                        return dir * ((a.params || 0) - (b.params || 0));
                    }
                    return 0;
                });
            },

            toggleTableSort(column) {
                if (this.hfTableSort === column) {
                    this.hfTableSortDir = this.hfTableSortDir === 'asc' ? 'desc' : 'asc';
                } else {
                    this.hfTableSort = column;
                    // Name and rank read more naturally as ascending by default
                    this.hfTableSortDir = (column === 'name' || column === 'rank') ? 'asc' : 'desc';
                }
            },

            syncTableSortToDropdown() {
                const map = {
                    largest:      { col: 'size',      dir: 'desc' },
                    smallest:     { col: 'size',      dir: 'asc'  },
                    most_params:  { col: 'params',    dir: 'desc' },
                    least_params: { col: 'params',    dir: 'asc'  },
                    downloads:    { col: 'downloads', dir: 'desc' },
                    trending:     { col: 'downloads', dir: 'desc' },
                    created:      { col: 'downloads', dir: 'desc' },
                    updated:      { col: 'downloads', dir: 'desc' },
                };
                const m = map[this.hfSearchSort];
                if (m) {
                    this.hfTableSort = m.col;
                    this.hfTableSortDir = m.dir;
                }
            },

            // Pagination helpers
            getPagedModels(tab) {
                const page = this.hfPage[tab] || 1;
                const size = this.hfPageSize;
                let list;
                if (tab === 'trending') list = this.hfRecommended.trending || [];
                else if (tab === 'popular') list = this.hfRecommended.popular || [];
                else list = this.hfSearchResults || [];
                // Apply table sorting
                const sorted = this.sortModels(list);
                return sorted.slice((page - 1) * size, page * size);
            },

            getTotalPages(tab) {
                let total;
                if (tab === 'trending') total = (this.hfRecommended.trending || []).length;
                else if (tab === 'popular') total = (this.hfRecommended.popular || []).length;
                else total = (this.hfSearchResults || []).length;
                const maxPages = tab === 'search' ? 10 : 5;
                return Math.min(Math.ceil(total / this.hfPageSize), maxPages);
            },

            setPage(tab, page) {
                this.hfPage[tab] = page;
            },

            // Search
            asyncup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_unsafe();
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
      const short num_k = K - k_blocks * BK;
      threadgroup_barrier(mem_flags::mem_threadgroup);
      loader_x.load_safe(short2(num_k, BM));
      loader_w.load_safe(short2(BN, num_k));
      threadgroup_barrier(mem_flags::mem_threadgroup);
      mma_op.mma(Xs, Ws);
    } else {
      for (int k = 0; k < K; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_unsafe();
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    }
  }

  // Store results to device memory
  threadgroup_barrier(mem_flags::mem_threadgroup);
  if (num_els < BM) {
    mma_op.store_result_safe(y, N, short2(BN, num_els));
  } else {
    mma_op.store_result(y, N);
  }
}

template <typename T>
METAL_FUNC void adjust_matrix_offsets(
    const device T*& x,
    const device uint32_t*& w,
    const device T*& scales,
    const device T*& biases,
    device T*& y,
    int output_stride,
    const constant int& x_batch_ndims,
    const constant int* x_shape,
    const constant int64_t* x_strides,
    const constant int& w_batch_ndims,
    const constant int* w_shape,
    const constant int64_t* w_strides,
    const constant int64_t* s_strides,
    const constant int64_t* b_strides,
    uint3 tid [[threadgroup_position_in_grid]]) {
  // Set the input/output matrices
  uint32_t x_idx = tid.z;
  uint32_t w_idx = tid.z;
  if (x_batch_ndims == 1) {
    x += x_idx * x_strides[0];
  } else {
    x += elem_to_loc(x_idx, x_shape, x_strides, x_batch_ndims);
  }
  if (w_batch_ndims == 1) {
    w += w_idx * w_strides[0];
    scales += w_idx * s_strides[0];
    biases += w_idx * b_strides[0];
  } else {
    ulong3 idx = elem_to_loc_broadcast(
        w_idx, w_shape, w_strides, s_strides, b_strides, w_batch_ndims);
    w += idx.x;
    scales += idx.y;
    biases += idx.z;
  }
  y += tid.z * output_stride;
}

template <typename T>
METAL_FUNC void adjust_matrix_offsets(
    const device T*& x,
    const device uint32_t*& w,
    const device T*& scales,
    const device T*& biases,
    const device uint32_t* lhs_indices,
    const device uint32_t* rhs_indices,
    device T*& y,
    int output_stride,
    const constant int& batch_ndims,
    const constant int* batch_shape,
    const constant int64_t* lhs_strides,
    const constant int64_t* rhs_strides,
    const constant int& x_batch_ndims,
    const constant int* x_shape,
    const constant int64_t* x_strides,
    const constant int& w_batch_ndims,
    const constant int* w_shape,
    const constant int64_t* w_strides,
    const constant int64_t* s_strides,
    const constant int64_t* b_strides,
    uint3 tid [[threadgroup_position_in_grid]]) {
  // Set the input/output matrices
  uint32_t x_idx;
  uint32_t w_idx;
  if (batch_ndims == 1) {
    x_idx = lhs_indices[tid.z * lhs_strides[0]];
    w_idx = rhs_indices[tid.z * rhs_strides[0]];
  } else {
    ulong2 idx = elem_to_loc_broadcast(
        tid.z, batch_shape, lhs_strides, rhs_strides, batch_ndims);
    x_idx = lhs_indices[idx.x];
    w_idx = rhs_indices[idx.y];
  }
  if (x_batch_ndims == 1) {
    x += x_idx * x_strides[0];
  } else {
    x += elem_to_loc(x_idx, x_shape, x_strides, x_batch_ndims);
  }
  if (w_batch_ndims == 1) {
    w += w_idx * w_strides[0];
    scales += w_idx * s_strides[0];
    biases += w_idx * b_strides[0];
  } else {
    ulong3 idx = elem_to_loc_broadcast(
        w_idx, w_shape, w_strides, s_strides, b_strides, w_batch_ndims);
    w += idx.x;
    scales += idx.y;
    biases += idx.z;
  }
  y += tid.z * output_stride;
}

template <typename T, int group_size, int bits, int D, bool batched>
[[kernel]] void affine_qmv_quad(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(str(path),
                            "has_readme": has_readme,
                        })
            return models

        return await asyncio.to_thread(_scan)

    async def start_upload(
        self,
        model_path: str,
        repo_id: str,
        token: str,
        readme_source_path: str = "",
        auto_readme: bool = True,
        redownload_notice: bool = False,
        private: bool = False,
    ) -> UploadTask:
        """Queue a model upload to HuggingFace Hub.

        Args:
            model_path: Local path to the oQ model directory.
            repo_id: Target HuggingFace repository ID (e.g., 'user/model-oQ4').
            token: HuggingFace write token.
            readme_source_path: Optional path to model whose README.md to copy.
            auto_readme: If True and no readme_source_path, generate a basic README.
            private: If True, create a private repository.

        Returns:
            The created UploadTask.

        Raises:
            ValueError: If model path is invalid or upload is already queued.
        """
        source = Path(model_path)
        if not source.exists() or not source.is_dir():
            raise ValueError(f"Model directory not found: {model_path}")

        if not (source / "config.json").exists():
            raise ValueError(f"Not a valid model directory (no config.json): {model_path}")

        repo_id = repo_id.strip()
        if "/" not in repo_id or len(repo_id.split("/")) != 2:
            raise ValueError(
                f"Invalid repository ID: '{repo_id}'. "
                "Expected format: 'owner/model' (e.g., 'user/Llama-3B-oQ4')"
            )

        # Check for duplicate active uploads
        for task in self._tasks.values():
            if task.repo_id == repo_id and task.status in _ACTIVE_STATUSES:
                raise ValueError(
                    f"Upload to '{repo_id}' is already in progress"
                )

        model_name = source.name
        total_size = sum(
            f.stat().st_size for f in source.rglob("*") if f.is_file()
        )

        task_id = str(uuid.uuid4())
        task = UploadTask(
            task_id=task_id,
            model_name=model_name,
            model_path=model_path,
            repo_id=repo_id,
            total_size=total_size,
        )
        self._tasks[task_id] = task

        self._active_tasks[task_id] = asyncio.create_task(
            self._run_upload(task_id, token, readme_source_path, auto_readme, redownload_notice, private)
        )

        logger.info(f"Upload queued: {model_name} -> {repo_id} (task_id={task_id})")
        return task

    async def cancel_upload(self, task_id: str) -> bool:
        """Cancel an active or pending upload.

        Args:
            task_id: The task ID to cancel.

        Returns:
            True if the task was found and cancelled.
        """
        task = self._tasks.get(task_id)
        if task is None:
            return False

        if task.status not in _ACTIVE_STATUSES:
            return False

        self._cancelled.add(task_id)
        task.status = UploadStatus.CANCELLED

        active_task = self._active_tasks.pop(task_id, None)
        if active_task and not active_task.done():
            active_task.cancel()

        logger.info(f"Upload cancelled: {task.model_name} (task_id={task_id})")
        return True

    def remove_task(self, task_id: str) -> bool:
        """Remove a completed, failed, or cancelled task from the list.

        Args:
            task_id: The task ID to remove.

        Returns:
            True if the task was found and removed.
        """
        task = self._tasks.get(task_id)
        if task is None:
            return False

        if task.status in _ACTIVE_STATUSES:
            return False

        del self._tasks[task_id]
        self._cancelled.discard(task_id)
        return True

    def get_tasks(self) -> list[dict]:
        """Return all tasks as serializable dicts, ordered by creation time."""
        return [
            task.to_dict()
            for task in sorted(self        comment: "Row label for the SpecPrefill draft-model picker"),
                    sublabel: String(localized: "settings.experimental.specprefill.draft.sub",
                                     defaultValue: "Small model sharing tokenizer with target.",
                                     comment: "Sublabel for the SpecPrefill draft-model picker")) {
                    Popup(
                        selection: vm.bindProfile($vm.specprefillDraftModel),
                        width: 260,
                        options: vm.draftModelOptions()
                    )
                }
                Row(label: String(localized: "settings.experimental.specprefill.keep_rate.label",
                                  defaultValue: "Keep Rate",
                                  comment: "Row label for the SpecPrefill keep-rate dropdown")) {
                    Popup(
                        selection: vm.bindProfile($vm.specprefillKeepPct),
                        width: 320,
                        options: ModelSettingsScreenVM.specprefillKeepPctOptions
                    )
                }
                Row(label: String(localized: "settings.experimental.specprefill.threshold.label",
                                  defaultValue: "Threshold",
                                  comment: "Row label for the SpecPrefill threshold field"),
                    sublabel: String(localized: "settings.experimental.specprefill.threshold.sub",
                                     defaultValue: "Min prompt tokens to trigger (shorter prompts use full prefill).",
                                     comment: "Sublabel for the SpecPrefill threshold field")) {
                    TextInput(text: vm.bindProfile($vm.specprefillThreshold),
                              placeholder: "8192", mono: true, suffix: "tk", width: 110)
                }
            }

            // DFlash
            Row(label: String(localized: "settings.experimental.dflash.label",
                              defaultValue: "DFlash",
                              comment: "Row label for the DFlash toggle"),
                sublabel: dflashSublabel) {
                Toggle("", isOn: vm.bindProfile($vm.dflashEnabled))
                    .labelsHidden().toggleStyle(.switch)
                    .disabled(dflashToggleDisabled)
                    .help(dflashHelp)
            }
            if vm.dflashEnabled {
                Row(label: String(localized: "settings.experimental.dflash.draft.label",
                                  defaultValue: "DFlash Draft Model",
                                  comment: "Row label for the DFlash draft-model picker")) {
                    Popup(
                        selection: vm.bindProfile($vm.dflashDraftModel),
                        width: 260,
                        options: vm.draftModelOptions()
                    )
                }
                Row(label: String(localized: "settings.experimental.dflash.draft_quant.label",
                                  defaultValue: "Draft Quantization",
                                  comment: "Row label for the DFlash draft quantization toggle"),
                    sublabel: String(localized: "settings.experimental.dflash.draft_quant.sub",
                                     defaultValue: "Enable quantization for the draft model (weight, activation bits & group size).",
                                     comment: "Sublabel for the DFlash draft quantization toggle")) {
                    Toggle("", isOn: vm.bindProfile($vm.dflashDraftQuantEnabled))
                        .labelsHidden().toggleStyle(.switch)
                }
                if vm.dflashDraftQuantEnabled {
                    Row(label: String(localized: "settings.experimental.dflash.draft_quant_weight.label",
                                      defaultValue: "Weight Bits",
                                      comment: "Row label for the DFlash draft quantization weight bits picker")) {
                        Popup(
                            selection: vm.bindProfile($vm.dflashDraft searchHFModels() {
                if (!this.hfSearchQuery.trim()) return;
                this.hfSearchLoading = true;
                this.hfRecommendedTab = 'search';
                this.hfPage.search = 1;
                // Sync table sort with dropdown choice so the frontend re-sort
                // does not override what the backend returned
                this.syncTableSortToDropdown();
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 15000);
                try {
                    const params = new URLSearchParams({
                        q: this.hfSearchQuery,
                        sort: this.hfSearchSort,
                        limit: '100',
                        mlx_only: this.hfMlxOnly,
                    });
                    // Add filter parameters if set. Sizes use binary GiB to match
                    // _format_model_size on the backend.
                    const GIB = 1024 * 1024 * 1024;
                    if (this.hfSearchMinParams) params.set('min_params', (parseFloat(this.hfSearchMinParams) * 1e9).toString());
                    if (this.hfSearchMaxParams) params.set('max_params', (parseFloat(this.hfSearchMaxParams) * 1e9).toString());
                    if (this.hfSearchMaxSize) params.set('max_size', (parseFloat(this.hfSearchMaxSize) * GIB).toString());
                    if (this.hfSearchMinSize) params.set('min_size', (parseFloat(this.hfSearchMinSize) * GIB).toString());
                    // Wire largest/smallest sort params to backend
                    if (this.hfSearchSort === 'largest') {
                        params.set('sort_by_size', 'true');
                        params.set('sort_ascending', 'false');
                    } else if (this.hfSearchSort === 'smallest') {
                        params.set('sort_by_size', 'true');
                        params.set('sort_ascending', 'true');
                    }


                    const response = await fetch(`/admin/api/hf/search?${params}`, { signal: controller.signal });
                    if (response.ok) {
                        const data = await response.json();
                        this.hfTokenInvalid = !!data.hf_token_invalid;
                        this.hfSearchResults = data.models || [];
                        this.hfSearchLoaded = true;
                        // Save to search history
                        this.addSearchHistory(this.hfSearchQuery.trim());
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.hfError = data.detail || 'Search failed';
                        setTimeout(() => { this.hfError = ''; }, 5000);
                    }
                } catch (err) {
                    if (err.name === 'AbortError') {
                        this.hfError = 'HuggingFace request timed out. The service may be unavailable.';
                    } else {
                        this.hfError = 'Failed to connect to HuggingFace.';
                    }
                    setTimeout(() => { this.hfError = ''; }, 5000);
                    console.error('Search failed:', err);
                } finally {
                    clearTimeout(timeoutId);
                    this.hfSearchLoading = false;
                }
            },

            clearHFSearchFilters() {
                this.hfSearchMinParams = '';
                this.hfSearchMaxParams = '';
                this.hfSearchMaxSize = '';
                this.hfSearchMinSize = '';
                if (this.hfSearchQuery.trim()) this.immediateSearch();
            },

            debounceSearch() {
                clearTimeout(this.hfSearchDebounceTimer);
                if (!this.hfSearchQuery.trim()) return;
                this.hfSearchDebounceTimer = setTimeout(() => this.searchHFModels(), 500);
            },

            immediateSearch() {
            2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint quad_gid [[quadgroup_index_in_threadgroup]],
    uint quad_lid [[thread_index_in_quadgroup]]) {
  if (batched) {
    int M = x_shape[x_batch_ndims];
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        out_vec_size * M,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }
  qmv_quad_impl<T, group_size, bits, D>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      quad_gid,
      quad_lid);
}

template <typename T, int group_size, int bits, bool batched>
[[kernel]] void affine_qmv_fast(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  if (batched) {
    int M = x_shape[x_batch_ndims];
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        out_vec_size * M,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }
  qmv_fast_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      simd_gid,
      simd_lid);
}

// Symmetric variant: skips biases DRAM load; computes bias = -scale*ratio (I-B).
template <typename T, int group_size, int bits, bool batched>
[[kernel]] void affine_qmv_fast_sym(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],  // bound but not read
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  if (batched) {
    int M = x_shape[x_batch_ndims];
    adjust_matrix_offsets<T>(
        x, w, scales, biases, y,
        out_vec_size * M,
        x_batch_ndims, x_shape, x_strides,
        w_batch_ndims, w_shape, w_strides,
        s_strides, b_stride._tasks.values(), key=lambda t: t.created_at)
        ]

    async def shutdown(self) -> None:
        """Cancel all active uploads and clean up."""
        for task_id, active_task in list(self._active_tasks.items()):
            if not active_task.done():
                active_task.cancel()
                task = self._tasks.get(task_id)
                if task and task.status == UploadStatus.UPLOADING:
                    task.status = UploadStatus.CANCELLED
        self._active_tasks.clear()
        logger.info("HF Uploader shut down")

    async def _run_upload(
        self,
        task_id: str,
        token: str,
        readme_source_path: str,
        auto_readme: bool,
        redownload_notice: bool,
        private: bool,
    ) -> None:
        """Execute an upload task with semaphore-guarded sequential processing."""
        from huggingface_hub import HfApi

        task = self._tasks[task_id]
        tmp_readme: Optional[Path] = None

        try:
            async with self._upload_sem:
                if task_id in self._cancelled:
                    return

                task.status = UploadStatus.UPLOADING
                task.started_at = time.time()

                model_path = Path(task.model_path)
                api = HfApi()

                # Create repo (exist_ok handles already-existing repos)
                await asyncio.to_thread(
                    api.create_repo,
                    repo_id=task.repo_id,
                    token=token,
                    exist_ok=True,
                    private=private,
                )

                if task_id in self._cancelled:
                    return

                # Handle README
                readme_in_model = model_path / "README.md"
                if readme_source_path:
                    source_readme = Path(readme_source_path) / "README.md"
                    if source_readme.exists():
                        shutil.copy2(source_readme, readme_in_model)
                        tmp_readme = readme_in_model
                elif auto_readme and not _has_meaningful_readme(model_path):
                    try:
                        with open(model_path / "config.json") as f:
                            config = json.load(f)
                    except Exception:
                        config = {}
                    readme_content = _generate_model_card(
                        task.model_name, config,
                        redownload_notice=redownload_notice,
                    )
                    readme_in_model.write_text(readme_content, encoding="utf-8")
                    tmp_readme = readme_in_model

                if task_id in self._cancelled:
                    return

                # Upload the entire model folder
                # upload_folder is blocking; run in thread
                task.progress = 10.0  # Signal that upload has started

                await asyncio.to_thread(
                    api.upload_folder,
                    folder_path=str(model_path),
                    repo_id=task.repo_id,
                    token=token,
                    commit_message=f"Upload {task.model_name} via oMLX",
                )

                if task_id in self._cancelled:
                    return

                # Success
                task.status = UploadStatus.COMPLETED
                task.progress = 100.0
                task.completed_at = time.time()
                task.repo_url = f"https://huggingface.co/{task.repo_id}"

                elapsed = task.completed_at - task.started_at
                logger.info(
                    f"Upload completed: {task.model_name} -> {task.repo_id} "
                    f"({elapsed:.0f}s, {_format_size(task.total_size)})"
                )

        except asyncio.CancelledError:
            if task.status not in (UploadStatus.CANCELLED, UploadStatus.FAILED):
                task.status = UploadStatus.CANCELLED
        except Exception as e:
            if task_id not in self._cancelled:
                task.status = UploadStatus.FAILED
          QuantWeightBits),
                            width: 110,
                            options: ModelSettingsScreenVM.dflashDraftQuantWeightBitsOptions
                        )
                    }
                    Row(label: String(localized: "settings.experimental.dflash.draft_quant_activation.label",
                                      defaultValue: "Activation Bits",
                                      comment: "Row label for the DFlash draft quantization activation bits picker")) {
                        Popup(
                            selection: vm.bindProfile($vm.dflashDraftQuantActivationBits),
                            width: 110,
                            options: ModelSettingsScreenVM.dflashDraftQuantActivationBitsOptions
                        )
                    }
                    Row(label: String(localized: "settings.experimental.dflash.draft_quant_group.label",
                                      defaultValue: "Group Size",
                                      comment: "Row label for the DFlash draft quantization group size picker")) {
                        Popup(
                            selection: vm.bindProfile($vm.dflashDraftQuantGroupSize),
                            width: 110,
                            options: ModelSettingsScreenVM.dflashDraftQuantGroupSizeOptions
                        )
                    }
                }
                Row(label: String(localized: "settings.experimental.dflash.max_ctx.label",
                                  defaultValue: "Max Context (fallback)",
                                  comment: "Row label for the DFlash max-context fallback field"),
                    sublabel: String(localized: "settings.experimental.dflash.max_ctx.sub",
                                     defaultValue: "Prompts at or above this token count switch to BatchedEngine. Empty = unlimited.",
                                     comment: "Sublabel describing the DFlash max-context fallback")) {
                    TextInput(text: vm.bindProfile($vm.dflashMaxCtx),
                              placeholder: String(localized: "settings.experimental.dflash.max_ctx.placeholder",
                                                  defaultValue: "unlimited",
                                                  comment: "Placeholder shown when DFlash max-context is unset (no cap)"),
                              mono: true, suffix: "tk", width: 130)
                }
                Row(label: String(localized: "settings.experimental.dflash.verify_mode.label",
                                  defaultValue: "Verify Mode",
                                  comment: "Row label for the DFlash verifier algorithm picker"),
                    sublabel: String(localized: "settings.experimental.dflash.verify_mode.sub",
                                     defaultValue: "Verifier algorithm. \"adaptive\" shrinks block size when acceptance drops; \"off\" disables speculative verify.",
                                     comment: "Sublabel for the DFlash verify mode picker")) {
                    Popup(
                        selection: vm.bindProfile($vm.dflashVerifyMode),
                        width: 140,
                        options: ModelSettingsScreenVM.dflashVerifyModeOptions
                    )
                }
                Row(label: String(localized: "settings.experimental.dflash.window_size.label",
                                  defaultValue: "Draft Window Size",
                                  comment: "Row label for the DFlash draft sliding-attention window size field"),
                    sublabel: String(localized: "settings.experimental.dflash.window_size.sub",
                                     defaultValue: "Draft model sliding-attention window. Empty = dflash default (1024).",
                                     comment: "Sublabel for the DFlash draft window size field")) {
                    TextInput(text: vm.bindProfile($vm.dflashDraftWindowSize),
                              placeholder: "1024", mono: true, width: 110)
         clearTimeout(this.hfSearchDebounceTimer);
                this.searchHFModels();
            },

            formatParamCount(params) {
                if (!params) return null;
                if (params >= 1e12) return (params / 1e12).toFixed(1) + 'T';
                if (params >= 1e9) return (params / 1e9).toFixed(1) + 'B';
                if (params >= 1e6) return (params / 1e6).toFixed(1) + 'M';
                return params.toString();
            },

            // Search history
            addSearchHistory(query) {
                let history = this.hfSearchHistory.filter(h => h !== query);
                history.unshift(query);
                history = history.slice(0, 5);
                this.hfSearchHistory = history;
                localStorage.setItem('hfSearchHistory', JSON.stringify(history));
            },

            selectSearchHistory(query) {
                this.hfSearchQuery = query;
                this.hfSearchHistoryOpen = false;
                this.searchHFModels();
            },

            closeSearchHistory() {
                setTimeout(() => { this.hfSearchHistoryOpen = false; }, 150);
            },

            // Model detail modal
            async openModelDetail(repoId) {
                this.hfModelDetailLoading = true;
                this.hfModelDetail = null;
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 15000);
                try {
                    const params = new URLSearchParams({ repo_id: repoId });
                    const response = await fetch(`/admin/api/hf/model-info?${params}`, { signal: controller.signal });
                    if (response.ok) {
                        this.hfModelDetail = await response.json();
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.hfError = data.detail || 'Failed to fetch model info';
                        setTimeout(() => { this.hfError = ''; }, 5000);
                    }
                } catch (err) {
                    if (err.name === 'AbortError') {
                        this.hfError = 'HuggingFace request timed out. The service may be unavailable.';
                    } else {
                        this.hfError = 'Failed to connect to HuggingFace.';
                    }
                    setTimeout(() => { this.hfError = ''; }, 5000);
                    console.error('Failed to fetch model info:', err);
                } finally {
                    clearTimeout(timeoutId);
                    this.hfModelDetailLoading = false;
                }
            },

            closeModelDetail() {
                this.hfModelDetail = null;
                this.hfModelDetailLoading = false;
                this.msModelDetail = null;
                this.msModelDetailLoading = false;
            },

            formatFileSize(bytes) {
                if (!bytes) return '';
                if (bytes < 1024) return bytes + ' B';
                if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
                if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
                return (bytes / (1024 * 1024 * 1024)).toFixed(1) + ' GB';
            },

            // =================================================================
            // ModelScope Downloader Functions
            // =================================================================

            async initMsDownloader() {
                if (this.msInitialized) return;
                this.msInitialized = true;
                try {
                    const response = await fetch('/admin/api/ms/status');
                    if (response.ok) {
                        const data = await response.json();
                        this.msAvailable = data.available === true;
                    } else {
          s, tid);
  }
  qmv_fast_impl<T, group_size, bits, /*symmetric=*/true>(
      w, scales, biases, x, y, in_vec_size, out_vec_size, tid, simd_gid, simd_lid);
}

template <typename T, const int group_size, const int bits, bool batched>
[[kernel]] void affine_qmv(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  if (batched) {
    int M = x_shape[x_batch_ndims];
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        out_vec_size * M,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }
  qmv_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      simd_gid,
      simd_lid);
}

template <
    typename T,
    int group_size,
    int bits,
    int vecs_per_tg,
    int k_lanes,
    bool batched>
[[kernel]] void affine_qmv_wide(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    const constant int& M,
    const constant int& x_batch_ndims,
    const constant int* x_shape,
    const constant int64_t* x_strides,
    const constant int& w_batch_ndims,
    const constant int* w_shape,
    const constant int64_t* w_strides,
    const constant int64_t* s_strides,
    const constant int64_t* b_strides,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  if (batched) {
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        out_vec_size * M,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }
  qmv_wide_impl<T, group_size, bits, vecs_per_tg, k_lanes>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      M,
      tid,
      simd_gid,
      simd_lid);
}

// Symmetric wide variant: skips biases DRAM load (I-B).
template <typename T, int group_size, int bits, int vecs_per_tg, int k_lanes, bool batched>
[[kernel]] void affine_qmv_wide_sym(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,  // bound but not read
    const device T* x,
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    const constant int& M,
    const constant int& x_batch_ndims,
    const constant int* x_shape,
    const constant int64_t* x_strides,
    const constant int& w_batch_ndims,
    const constant int* w_shape,
    const constant int64_t* w_strides,
    const constant int64_t* s_strides,
    const constant int64_t* b_strides,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  if (batched) {
    adjust_matrix_offsets<T>(
        x, w, scales, biases, y,
        out_vec_size * M,
        x_batch_ndims, x_shape, x_strides,
        w_batch_ndims, w_shape, w_strides,
        s_      task.error = str(e)
                logger.error(f"Upload failed for {task.model_name}: {e}")
        finally:
            # Clean up copied/generated README if we created it
            if tmp_readme and tmp_readme.exists():
                try:
                    tmp_readme.unlink()
                except Exception:
                    pass
            self._active_tasks.pop(task_id, None)


# ===== FILE: omlx/admin/ms_downloader.py =====

# SPDX-License-Identifier: Apache-2.0
"""ModelScope model downloader for oMLX admin panel.

Downloads models from ModelScope Hub using the modelscope SDK's snapshot_download
with directory-size-based progress polling.
"""

import asyncio
import logging
import os
import shutil
import time
import uuid
from pathlib import Path
from typing import Callable, Optional

import requests

from .hf_downloader import (
    DownloadStatus,
    DownloadTask,
    _format_model_size,
    _format_param_count,
)

logger = logging.getLogger(__name__)

# Check if modelscope SDK is available
MS_SDK_AVAILABLE = False
try:
    from modelscope import snapshot_download as ms_snapshot_download
    from modelscope.hub.api import HubApi as MSHubApi

    MS_SDK_AVAILABLE = True
except ImportError:
    ms_snapshot_download = None  # type: ignore[assignment]
    MSHubApi = None  # type: ignore[assignment, misc]

# Timeout for ModelScope API calls (seconds).
_MS_API_TIMEOUT = 15

# Seconds with no download progress before considering the download stalled.
_STALL_TIMEOUT = 300

# Default ModelScope API base URL.
_DEFAULT_MS_ENDPOINT = "https://modelscope.cn"

# Minimum downloads to be included in recommendations.
_MIN_DOWNLOADS = 50


def _get_ms_endpoint() -> str:
    """Get the configured ModelScope endpoint URL."""
    # Check environment variable first (set by CLI/settings)
    endpoint = os.environ.get("MODELSCOPE_DOMAIN", "")
    if endpoint:
        return endpoint.rstrip("/")

    try:
        from ..settings import get_settings

        endpoint = get_settings().modelscope.endpoint
        if endpoint:
            return endpoint.rstrip("/")
    except (RuntimeError, AttributeError):
        pass

    return _DEFAULT_MS_ENDPOINT


def _get_ms_api():
    """Create ModelScope HubApi instance.

    Returns:
        HubApi instance or None if SDK not available.
    """
    if not MS_SDK_AVAILABLE:
        return None
    return MSHubApi()


def _extract_model_size_from_files(file_list: list) -> int:
    """Calculate total file size from a list of file metadata dicts."""
    total = 0
    for f in file_list:
        size = f.get("Size") or f.get("size") or 0
        if isinstance(size, (int, float)):
            total += int(size)
    return total


# ---------------------------------------------------------------------------
# Per-model enrichment (size + param count)
#
# ModelScope's list_models endpoint returns Path/Name/Downloads/Likes/Stars
# but rarely populates StorageSize, and never returns a parameter count.
# To match HuggingFace's recommended-models card data, we enrich each entry
# with a config.json fetch (for params) and — when StorageSize was missing —
# a model-detail fetch (for size).
#
# Cached in-process for 24 hours since config.json content for a model
# doesn't change in practice; this keeps subsequent page loads of the
# Downloads tab essentially free.

_ENRICH_CACHE: dict[str, tuple[float, dict]] = {}
_ENRICH_CACHE_TTL = 24 * 3600  # 24h — config.json is effectively immutable
_ENRICH_CACHE_MAX = 1024       # bound memory under aggressive search/list use
_ENRICH_CONCURRENCY = 8        # parallel fetches per recommended/search call


def _enrich_cache_get(model_id: str) -> Optional[dict]:
    entry = _ENRICH_CACHE.get(model_id)
    if entry is None:
        return None
    ts, data = entry
    if time.time() - ts > _ENRICH_CACHE_TTL:
        _ENRICH_CACHE.pop(model_id, None)
        return None
    return data


def _enrich_cache_put(model_id: str, data: dict) -> None:
    if len(_ENRICH_CACHE) >= _ENRICH_CACHE_MAX:
        # Drop the oldest entry. O(N) on eviction but N is bounded a           }
                Row(label: String(localized: "settings.experimental.dflash.sink_size.label",
                                  defaultValue: "Draft Sink Size",
                                  comment: "Row label for the DFlash attention-sink tokens field"),
                    sublabel: String(localized: "settings.experimental.dflash.sink_size.sub",
                                     defaultValue: "Attention-sink tokens always kept in the window. Empty = dflash default (64).",
                                     comment: "Sublabel for the DFlash draft sink size field")) {
                    TextInput(text: vm.bindProfile($vm.dflashDraftSinkSize),
                              placeholder: "64", mono: true, width: 110)
                }
                Row(label: String(localized: "settings.experimental.dflash.mem_cache.label",
                                  defaultValue: "DFlash in-memory cache",
                                  comment: "Row label for the DFlash L1 in-memory cache toggle"),
                    sublabel: String(localized: "settings.experimental.dflash.mem_cache.sub",
                                     defaultValue: "DFlash L1 prefix snapshot cache in RAM.",
                                     comment: "Sublabel for the DFlash L1 in-memory cache toggle")) {
                    HStack(spacing: 8) {
                        if vm.dflashInMemoryCache {
                            TextInput(text: vm.bindProfile($vm.dflashInMemoryCacheGib),
                                      placeholder: "8", mono: true, suffix: "GiB", width: 110)
                        }
                        Toggle("", isOn: vm.bindProfile($vm.dflashInMemoryCache))
                            .labelsHidden().toggleStyle(.switch)
                    }
                }
                if vm.dflashInMemoryCache {
                    Row(label: String(localized: "settings.experimental.dflash.mem_cache_entries.label",
                                      defaultValue: "Cache Entries",
                                      comment: "Row label for the DFlash L1 in-memory cache max entries field"),
                        sublabel: String(localized: "settings.experimental.dflash.mem_cache_entries.sub",
                                         defaultValue: "Maximum prefix snapshots kept in RAM. Each entry stores KV + draft GDN state.",
                                         comment: "Sublabel for the DFlash L1 cache max entries field")) {
                        TextInput(text: vm.bindProfile($vm.dflashInMemoryCacheMaxEntries),
                                  placeholder: "4", mono: true, width: 110)
                    }
                }
                Row(label: String(localized: "settings.experimental.dflash.ssd_cache.label",
                                  defaultValue: "DFlash SSD cache",
                                  comment: "Row label for the DFlash L2 SSD cache toggle"),
                    sublabel: dflashSsdSublabel) {
                    Toggle("", isOn: vm.bindProfile($vm.dflashSsdCache))
                        .labelsHidden().toggleStyle(.switch)
                        .disabled(!(vm.model?.dflashSsdCacheAvailable ?? false) || !vm.dflashInMemoryCache)
                }
                if vm.dflashSsdCache && (vm.model?.dflashSsdCacheAvailable ?? false) {
                    Row(label: String(localized: "settings.experimental.dflash.ssd_cache_size.label",
                                      defaultValue: "SSD Cache Size",
                                      comment: "Row label for the DFlash L2 SSD cache disk budget field"),
                        sublabel: String(localized: "settings.experimental.dflash.ssd_cache_size.sub",
                                         defaultValue: "Disk budget for L2 spill; oldest entries are evicted when exceeded.",
                                         comment: "Sublabel for the DFlash SSD cache size field")) {
                        TextInput(text: vm.bindProfile($vm.dflashSsdCacheGib),
                                  placeholder: "20", mono: tr              this.msAvailable = false;
                    }
                } catch (err) {
                    this.msAvailable = false;
                    console.error('Failed to check MS status:', err);
                }
                if (this.msAvailable) {
                    await this.loadMSTasks();
                }
            },

            async startMSDownload() {
                let repoId = this.msRepoId.trim();
                if (!repoId) return;

                // Default owner to mlx-community if not specified
                if (!repoId.includes('/')) {
                    repoId = 'mlx-community/' + repoId;
                }

                this.msError = '';
                this.msSuccess = '';
                this.msDownloading = true;
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 20000);

                try {
                    const response = await fetch('/admin/api/ms/download', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            model_id: repoId,
                            ms_token: this.msToken || '',
                        }),
                        signal: controller.signal,
                    });

                    if (response.ok) {
                        this.msSuccess = window.t('js.success.download_started').replace('{repo_id}', repoId);
                        this.msRepoId = '';
                        await this.loadMSTasks();
                        this.startMSRefresh();
                        setTimeout(() => { this.msSuccess = ''; }, 5000);
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.msError = data.detail || window.t('js.error.start_download_failed');
                    }
                } catch (err) {
                    if (err.name === 'AbortError') {
                        this.msError = 'ModelScope request timed out. The service may be unavailable.';
                    } else {
                        this.msError = window.t('js.error.start_download_connection');
                    }
                    console.error('Failed to start MS download:', err);
                } finally {
                    clearTimeout(timeoutId);
                    this.msDownloading = false;
                }
            },

            async loadMSTasks() {
                try {
                    const response = await fetch('/admin/api/ms/tasks');
                    if (response.ok) {
                        const data = await response.json();
                        this.msTasks = data.tasks || [];

                        const hasActive = this.msTasks.some(t =>
                            t.status === 'pending' || t.status === 'downloading');
                        if (!hasActive) {
                            this.stopMSRefresh();
                            if (this.msTasks.some(t => t.status === 'completed')) {
                                await this.loadHFModels();
                                await this.loadModels();
                            }
                        }

                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    }
                } catch (err) {
                    console.error('Failed to load MS tasks:', err);
                }
            },

            async cancelMSDownload(taskId) {
                try {
                    const response = await fetch(`/admin/api/ms/cancel/${taskId}`, {
                        method: 'POST',
                    });
                    if (response.ok) {
                        await this.loadMSTasks();
                    }
                } catch (err) {
                    console.error('Failestrides, b_strides, tid);
  }
  qmv_wide_impl<T, group_size, bits, vecs_per_tg, k_lanes, /*symmetric=*/true>(
      w, scales, biases, x, y, in_vec_size, out_vec_size, M, tid, simd_gid, simd_lid);
}

template <typename T, const int group_size, const int bits, bool batched>
[[kernel]] void affine_qvm(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  if (batched) {
    int M = x_shape[x_batch_ndims];
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        out_vec_size * M,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }
  qvm_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      simd_gid,
      simd_lid);
}

template <typename T, const int group_size, const int bits, int split_k = 32>
[[kernel]] void affine_qvm_split_k(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    const constant int& final_block_size [[buffer(15)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  int M = x_shape[x_batch_ndims];
  adjust_matrix_offsets<T>(
      x,
      w,
      scales,
      biases,
      y,
      out_vec_size * M,
      x_batch_ndims,
      x_shape,
      x_strides,
      w_batch_ndims,
      w_shape,
      w_strides,
      s_strides,
      b_strides,
      tid);

  // When (in_vec_size % split_k != 0) the final block needs to be smaller
  int in_vec_size_adj =
      tid.z % split_k == split_k - 1 ? final_block_size : in_vec_size;

  qvm_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size_adj,
      out_vec_size,
      tid,
      simd_gid,
      simd_lid);
}

template <
    typename T,
    const int group_size,
    const int bits,
    const bool aligned_N,
    const bool batched,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
[[kernel]] void affine_qmm_t(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& K [[buffer(5)]],
    const constant int& N [[buffer(6)]],
    const constant int& M [[buffer(7)]],
    const constant int& x_batch_ndims [[buffer(8)]],
    const constant int* x_shape [[buffer(9)]],
    const constant int64_t* x_strides [[buffer(10)]],
    const constant int& wt MAX
        # and evictions are rare in practice (24h TTL >> page-load rate).
        oldest = min(_ENRICH_CACHE, key=lambda k: _ENRICH_CACHE[k][0])
        _ENRICH_CACHE.pop(oldest, None)
    _ENRICH_CACHE[model_id] = (time.time(), data)


def _estimate_params_from_config(config: Optional[dict]) -> int:
    """Estimate decoder-transformer parameter count from a HF-style config.

    Handles dense Llama/Qwen/Mistral families and MoE variants
    (num_local_experts / num_experts). Returns 0 when required fields are
    missing — caller should render a blank rather than display a wrong
    number. The estimate is intentionally a rough headline figure (≈±5%);
    the goal is to surface "~7B" vs "~14B", not to match the checkpoint
    byte-for-byte.
    """
    if not isinstance(config, dict):
        return 0
    try:
        vocab_size = int(config.get("vocab_size", 0))
        hidden_size = int(config.get("hidden_size", 0))
        num_layers = int(config.get("num_hidden_layers", 0))
    except (TypeError, ValueError):
        return 0

    if not (vocab_size and hidden_size and num_layers):
        return 0

    try:
        intermediate_size = int(config.get("intermediate_size", 0))
        num_heads = int(config.get("num_attention_heads", 0))
        num_kv = int(config.get("num_key_value_heads", num_heads))
        head_dim = int(config.get("head_dim", 0)) or (
            hidden_size // num_heads if num_heads else 0
        )
        num_experts = int(
            config.get("num_local_experts")
            or config.get("num_experts")
            or 1
        )
        tie_embeddings = bool(config.get("tie_word_embeddings", True))
    except (TypeError, ValueError):
        return 0

    embeddings = vocab_size * hidden_size

    # Attention: Q + O are full hidden_size; K + V are reduced for GQA.
    if num_heads and head_dim:
        attn = (
            2 * hidden_size * (num_heads * head_dim)
            + 2 * hidden_size * (num_kv * head_dim)
        )
    else:
        attn = 4 * hidden_size * hidden_size

    # Gated MLP (Llama/Qwen style): gate + up + down projections.
    # MoE multiplies the FFN by the number of experts.
    if intermediate_size:
        ffn = num_experts * 3 * hidden_size * intermediate_size
    else:
        ffn = 8 * hidden_size * hidden_size

    layer_norms = 2 * hidden_size
    per_layer = attn + ffn + layer_norms

    total = embeddings + num_layers * per_layer + hidden_size
    if not tie_embeddings:
        total += vocab_size * hidden_size  # untied LM head

    return total


async def _fetch_model_config(model_id: str) -> Optional[dict]:
    """Fetch and parse a model's config.json from ModelScope.

    Returns None on any error (network, non-200, non-JSON) so callers can
    treat the field as absent without raising.
    """
    if not model_id:
        return None
    import json

    endpoint = _get_ms_endpoint()
    url = (
        f"{endpoint}/api/v1/models/{model_id}/repo"
        f"?FilePath=config.json&Revision=master"
    )
    try:
        resp = await asyncio.wait_for(
            asyncio.to_thread(requests.get, url, timeout=_MS_API_TIMEOUT),
            timeout=_MS_API_TIMEOUT + 5,
        )
        if resp.status_code != 200:
            return None
        return json.loads(resp.text)
    except Exception as e:
        logger.debug(f"config.json fetch failed for {model_id}: {e}")
        return None


async def _fetch_model_detail_size(model_id: str) -> int:
    """Fetch a model's storage size via the detail endpoint.

    Used as a fallback when list_models didn't populate StorageSize.
    Prefers ModelInfos.safetensor.model_size (weights only) and falls
    back to the repository StorageSize (weights + tokenizer + readme).
    Returns 0 on any error.
    """
    if not model_id:
        return 0
    endpoint = _get_ms_endpoint()
    url = f"{endpoint}/api/v1/models/{model_id}"
    try:
        resp = await asyncio.wait_for(
            asyncio.to_thread(requests.get, url, timeout=_MS_API_TIMEOUT),
            timeout=_MS_API_TIMEOUT + 5,
        )
        if reue, suffix: "GiB", width: 110)
                    }
                }
            }

            // VLM MTP — last row of the experimental group. Reveals the
            // draft-model picker and block-size field when enabled.
            Row(label: String(localized: "settings.experimental.vlm_mtp.label",
                              defaultValue: "VLM MTP",
                              comment: "Row label for the VLM MTP toggle"),
                sublabel: vlmMtpSublabel,
                isLast: !vm.vlmMtpEnabled) {
                Toggle("", isOn: vm.bindProfile($vm.vlmMtpEnabled))
                    .labelsHidden().toggleStyle(.switch)
                    .disabled(vlmMtpToggleDisabled)
                    .help(vm.vlmMtpConflictReason ?? "")
            }
            if vm.vlmMtpEnabled {
                Row(label: String(localized: "settings.experimental.vlm_mtp.draft.label",
                                  defaultValue: "VLM Draft Model",
                                  comment: "Row label for the VLM MTP draft-model picker"),
                    sublabel: String(localized: "settings.experimental.vlm_mtp.draft.sub",
                                     defaultValue: "Assistant drafter sharing the target's tokenizer.",
                                     comment: "Sublabel for the VLM MTP draft-model picker")) {
                    Popup(
                        selection: vm.bindProfile($vm.vlmMtpDraftModel),
                        width: 260,
                        options: vm.vlmMtpDraftModelOptions()
                    )
                }
                Row(label: String(localized: "settings.experimental.vlm_mtp.block_size.label",
                                  defaultValue: "Draft Block Size",
                                  comment: "Row label for the VLM MTP draft block-size field"),
                    sublabel: String(localized: "settings.experimental.vlm_mtp.block_size.sub",
                                     defaultValue: "Tokens drafted per round. Empty uses the mlx-vlm default.",
                                     comment: "Sublabel for the VLM MTP draft block-size field"),
                    isLast: true) {
                    TextInput(text: vm.bindProfile($vm.vlmMtpDraftBlockSize),
                              placeholder: "4", mono: true, width: 80)
                }
            }
        }
    }

    private var vlmMtpOwnsSpeculativePathReason: String {
        String(localized: "settings.speculative.conflict.vlm_mtp",
               defaultValue: "Disable VLM MTP before enabling this feature.",
               comment: "Tooltip / sublabel shown when another speculative feature can't be enabled because VLM MTP is on")
    }

    private var turboquantSublabel: String {
        if vm.vlmMtpEnabled { return vlmMtpOwnsSpeculativePathReason }
        return String(localized: "settings.experimental.turboquant.sub",
                      defaultValue: "Quantize the KV cache during prefill. Saves memory at a small quality cost.",
                      comment: "Sublabel describing TurboQuant KV cache")
    }

    private var specprefillSublabel: String {
        if vm.vlmMtpEnabled { return vlmMtpOwnsSpeculativePathReason }
        return String(localized: "settings.experimental.specprefill.sub",
                      defaultValue: "Attention-based sparse prefill for MoE/hybrid models.",
                      comment: "Sublabel describing SpecPrefill")
    }

    private var dflashToggleDisabled: Bool {
        !(vm.model?.dflashCompatible ?? true) || vm.vlmMtpEnabled
    }

    private var dflashHelp: String {
        if let reason = vm.model?.dflashCompatibilityReason,
           !(vm.model?.dflashCompatible ?? true) {
            return reason
        }
        return vm.vlmMtpEnabled ? vlmMtpOwnsSpeculativePathReason : ""
    }

    private var dflashSublabel: String {
        if let reason = vm.model?.dflashCompatibilityReason,
           !(vm.model?.dflashCompatible ?? true) {
            return reason
        }
        if vm.vlmMtpEnabled { return vlmMtpOwnsSpeculativePathRead to cancel MS download:', err);
                }
            },

            async retryMSDownload(taskId) {
                try {
                    const response = await fetch(`/admin/api/ms/retry/${taskId}`, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ ms_token: this.msToken || null }),
                    });
                    if (response.ok) {
                        await this.loadMSTasks();
                        this.startMSRefresh();
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.msError = data.detail || 'Retry failed';
                        setTimeout(() => { this.msError = ''; }, 5000);
                    }
                } catch (err) {
                    console.error('Failed to retry MS download:', err);
                }
            },

            async removeMSTask(taskId) {
                try {
                    const response = await fetch(`/admin/api/ms/task/${taskId}`, {
                        method: 'DELETE',
                    });
                    if (response.ok) {
                        await this.loadMSTasks();
                    }
                } catch (err) {
                    console.error('Failed to remove MS task:', err);
                }
            },

            startMSRefresh() {
                this.stopMSRefresh();
                this._msRefreshTimer = setInterval(() => {
                    this.loadMSTasks();
                }, 2000);
            },

            stopMSRefresh() {
                if (this._msRefreshTimer) {
                    clearInterval(this._msRefreshTimer);
                    this._msRefreshTimer = null;
                }
            },

            downloadMsModel(repoId) {
                this.msRepoId = repoId;
                this.startMSDownload();
            },

            // MS Recommended models
            async loadMsRecommendedModels() {
                this.msRecommendedLoading = true;
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 20000);
                try {
                    const response = await fetch(`/admin/api/ms/recommended?mlx_only=${this.msMlxOnly}`, { signal: controller.signal });
                    if (response.ok) {
                        const data = await response.json();
                        this.msRecommended = data;
                        this.msRecommendedLoaded = true;
                        this.msPage.trending = 1;
                        this.msPage.popular = 1;
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.msError = data.detail || 'Failed to load recommended models';
                        setTimeout(() => { this.msError = ''; }, 5000);
                    }
                } catch (err) {
                    if (err.name === 'AbortError') {
                        this.msError = 'ModelScope request timed out. The service may be unavailable.';
                    } else {
                        this.msError = 'Failed to connect to ModelScope.';
                    }
                    setTimeout(() => { this.msError = ''; }, 5000);
                    console.error('Failed to load MS recommended models:', err);
                } finally {
                    clearTimeout(timeoutId);
                    this.msRecommendedLoading = false;
                }
            },

            // MS Pagination helpers
            getMsPagedModels(tab) {
                const page = this.msPage[tab] || 1;
                const size = this.msPageSize;
                let list;
                if (tab === 'trending') list = (this.msRecommended.trending || []);
                else if (tab === 'popular') list =_batch_ndims [[buffer(11)]],
    const constant int* w_shape [[buffer(12)]],
    const constant int64_t* w_strides [[buffer(13)]],
    const constant int64_t* s_strides [[buffer(14)]],
    const constant int64_t* b_strides [[buffer(15)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  (void)lid;

  constexpr int BK_padded = (BK + 16 / sizeof(T));

  threadgroup T Xs[BM * BK_padded];
  threadgroup T Ws[BN * BK_padded];

  if (batched) {
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        M * N,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }
  qmm_t_impl<T, group_size, bits, aligned_N, BM, BK, BN>(
      w,
      scales,
      biases,
      x,
      y,
      Xs,
      Ws,
      K,
      N,
      M,
      K,
      tid,
      lid,
      simd_gid,
      simd_lid);
}

template <
    typename T,
    const int group_size,
    const int bits,
    const bool aligned_N,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
[[kernel]] void affine_qmm_t_splitk(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& K [[buffer(5)]],
    const constant int& N [[buffer(6)]],
    const constant int& M [[buffer(7)]],
    const constant int& k_partition_size [[buffer(8)]],
    const constant int& split_k_partition_stride [[buffer(9)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  (void)lid;

  constexpr int BK_padded = (BK + 16 / sizeof(T));
  constexpr int pack_factor = get_pack_factor<bits, 8>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();

  threadgroup T Xs[BM * BK_padded];
  threadgroup T Ws[BN * BK_padded];

  const int k_start = tid.z * k_partition_size;
  x += k_start;

  auto wl = (const device uint8_t*)w;
  wl += k_start * bytes_per_pack / pack_factor;
  scales += k_start / group_size;
  biases += k_start / group_size;
  y += tid.z * static_cast<int64_t>(split_k_partition_stride);

  qmm_t_impl<T, group_size, bits, aligned_N, BM, BK, BN>(
      (const device uint32_t*)wl,
      scales,
      biases,
      x,
      y,
      Xs,
      Ws,
      K,
      N,
      M,
      k_partition_size,
      tid,
      lid,
      simd_gid,
      simd_lid);
}

template <
    typename T,
    const int group_size,
    const int bits,
    const bool batched,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
[[kernel]] void affine_qmm_n(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& K [[buffer(5)]],
    const constant int& N [[buffer(6)]],
    const constant int& M [[buffer(7)]],
    const constant int& x_batch_ndims [[buffer(8)]],
    const constant int* x_shape [[buffer(9)]],
    const constant int64_t* x_strides [[buffer(10)]],
    const constant int& w_batch_ndims [[buffer(11)]],
    const constant int* w_shape [[buffer(12)]],
    const constant int64_t* w_strides [[buffer(13)]],
    const constant int64_t* s_strides [[buffer(14)]],
    const constant int64_t* b_strides [[buffer(15)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  (void)lid;

  constexpr int BK_padded = (BK + 16 / sizeof(T));
  constexpr int BN_padded = (BN + 16 / sizeof(T));

  threadgroup T Xs[BM * BK_padded];
  threadgroup T Ws[BK * BN_padded];

  if (batched) {
 sp.status_code != 200:
            return 0
        data = resp.json().get("Data") or {}
        model_infos = data.get("ModelInfos") or {}
        st = model_infos.get("safetensor") or {}
        size = st.get("model_size") or data.get("StorageSize") or 0
        return int(size) if isinstance(size, (int, float, str)) else 0
    except (TypeError, ValueError):
        return 0
    except Exception as e:
        logger.debug(f"model detail fetch failed for {model_id}: {e}")
        return 0


async def _enrich_ms_entry(entry: dict, sem: asyncio.Semaphore) -> dict:
    """Add size + params to a parsed model entry.

    Concurrent fetches are gated by `sem`; per-model results are cached
    in-process for 24h so subsequent page loads don't re-issue requests.
    Mutates and returns the same dict for ergonomic gather() pipelines.
    """
    model_id = entry.get("repo_id") or ""
    if not model_id:
        return entry

    cached = _enrich_cache_get(model_id)
    if cached is not None:
        c_size = cached.get("size") or 0
        c_params = cached.get("params") or 0
        if c_size and not entry.get("size"):
            entry["size"] = c_size
            entry["size_formatted"] = _format_model_size(c_size)
        if c_params:
            entry["params"] = c_params
            entry["params_formatted"] = _format_param_count(c_params)
        return entry

    async with sem:
        config_task = asyncio.create_task(_fetch_model_config(model_id))
        need_size = (entry.get("size") or 0) <= 0
        detail_task = (
            asyncio.create_task(_fetch_model_detail_size(model_id))
            if need_size else None
        )

        config = await config_task
        params = _estimate_params_from_config(config)

        size = entry.get("size") or 0
        if detail_task is not None:
            size = await detail_task

    _enrich_cache_put(model_id, {"size": size, "params": params})

    if size and not entry.get("size"):
        entry["size"] = size
        entry["size_formatted"] = _format_model_size(size)
    if params:
        entry["params"] = params
        entry["params_formatted"] = _format_param_count(params)
    return entry


def _parse_ms_model_entry(entry: dict) -> dict:
    """Parse a ModelScope API model entry into a normalized dict.

    Args:
        entry: Raw model dict from ModelScope API.

    Returns:
        Normalized model dict matching the HF format.
    """
    # Path is the organization/owner, Name is the model name
    # repo_id should be "owner/model" format
    path = entry.get("Path") or ""
    name = entry.get("Name") or ""
    if path and name:
        model_id = f"{path}/{name}"
    elif name:
        model_id = name
    else:
        model_id = path

    downloads = entry.get("Downloads") or 0
    likes = entry.get("Likes") or entry.get("Stars") or 0
    # StorageSize is the total size in bytes
    size = entry.get("StorageSize") or 0

    return {
        "repo_id": model_id,
        "name": name or model_id.split("/")[-1],
        "downloads": downloads,
        "likes": likes,
        "trending_score": 0,
        "size": size,
        "size_formatted": _format_model_size(size) if size > 0 else "",
        "params": None,
        "params_formatted": None,
    }


async def _fetch_ms_models_rest(
    query: str = "",
    page_size: int = 200,
) -> list[dict]:
    """Fetch models from ModelScope REST API without org restriction.

    Used when mlx_only is disabled to search across all organizations.

    Args:
        query: Optional search query to filter by model name.
        page_size: Number of models to fetch.

    Returns:
        List of raw model entry dicts from the API response.
    """
    endpoint = _get_ms_endpoint()
    url = f"{endpoint}/api/v1/models/"
    payload: dict = {"PageSize": page_size}
    if query:
        payload["Name"] = query
    try:
        resp = await asyncio.wait_for(
            asyncio.to_thread(
                requests.put, url, json=payload, timeout=_MS_API_TIMEOUT
            ),
            timeout=_MS_API_TIMEOUT + 5,
    son }
        return String(localized: "settings.experimental.dflash.sub",
                      defaultValue: "Block-diffusion speculative decoding. Single-stream only (requests run one at a time).",
                      comment: "Default sublabel for the DFlash toggle (used when the model is compatible)")
    }

    private var dflashSsdSublabel: String {
        if !(vm.model?.dflashSsdCacheAvailable ?? false) {
            return String(localized: "settings.experimental.dflash.ssd_cache.sub.unavailable",
                          defaultValue: "Enable the global paged SSD cache directory first.",
                          comment: "Sublabel for the DFlash SSD cache row when the global SSD cache directory isn't configured")
        }
        if !vm.dflashInMemoryCache {
            return String(localized: "settings.experimental.dflash.ssd_cache.sub.needs_l1",
                          defaultValue: "Requires the in-memory cache to be enabled.",
                          comment: "Sublabel for the DFlash SSD cache row when the L1 in-memory cache is off")
        }
        return String(localized: "settings.experimental.dflash.ssd_cache.sub",
                      defaultValue: "L2 spill of evicted L1 entries to disk.",
                      comment: "Default sublabel for the DFlash SSD cache toggle")
    }

    private var vlmMtpToggleDisabled: Bool {
        vm.vlmMtpConflictReason != nil
    }

    private var vlmMtpSublabel: String {
        if let reason = vm.vlmMtpConflictReason { return reason }
        return String(localized: "settings.experimental.vlm_mtp.sub",
                      defaultValue: "Multi-token prediction for vision-language models via an assistant drafter.",
                      comment: "Default sublabel for the VLM MTP toggle")
    }
}

// MARK: - Sampling validators
//
// Empty input is always valid and maps to nil — the server treats nil as
// "unset, fall back to model default". A non-empty value that fails to
// parse or falls outside the documented range is rejected before the
// patch is sent, so a slipped keystroke can't silently overwrite the
// server with an out-of-band value.

struct SamplingValidationError: Error, Equatable {
    let message: String
}

enum SamplingValidator {
    static func temperature(_ raw: String) -> Result<Double?, SamplingValidationError> {
        let label = String(localized: "settings.validator.temperature.name",
                           defaultValue: "Temperature",
                           comment: "Field name embedded in validation errors for temperature")
        return parseDouble(raw, label: label) { v in
            v >= 0 ? nil : String(localized: "settings.validator.temperature.range",
                                  defaultValue: "Temperature must be ≥ 0.",
                                  comment: "Validation error when temperature is below the allowed range")
        }
    }

    static func topP(_ raw: String) -> Result<Double?, SamplingValidationError> {
        let label = String(localized: "settings.validator.top_p.name",
                           defaultValue: "Top P",
                           comment: "Field name embedded in validation errors for top-p")
        return parseDouble(raw, label: label) { v in
            (v > 0 && v <= 1) ? nil : String(localized: "settings.validator.top_p.range",
                                             defaultValue: "Top P must be in (0, 1].",
                                             comment: "Validation error when top-p falls outside the allowed range")
        }
    }

    static func minP(_ raw: String) -> Result<Double?, SamplingValidationError> {
        let label = String(localized: "settings.validator.min_p.name",
                           defaultValue: "Min P",
                           comment: "Field name embedded in validation errors for min-p")
        return parseDouble(raw, label: label) { v in
            (v >= 0 && v <= 1) ? nil : String(localized: "settings.validator.min_p.range",
                                              defaultValue: "Min P must be in [0, 1]." (this.msRecommended.popular || []);
                else list = this.msSearchResults || [];
                return list.slice((page - 1) * size, page * size);
            },

            getMsTotalPages(tab) {
                let total;
                if (tab === 'trending') total = (this.msRecommended.trending || []).length;
                else if (tab === 'popular') total = (this.msRecommended.popular || []).length;
                else total = (this.msSearchResults || []).length;
                const maxPages = tab === 'search' ? 10 : 5;
                return Math.min(Math.ceil(total / this.msPageSize), maxPages);
            },

            setMsPage(tab, page) {
                this.msPage[tab] = page;
            },

            // MS Search
            async searchMSModels() {
                if (!this.msSearchQuery.trim()) return;
                this.msSearchLoading = true;
                this.msRecommendedTab = 'search';
                this.msPage.search = 1;
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 20000);
                try {
                    const params = new URLSearchParams({
                        q: this.msSearchQuery,
                        sort: this.msSearchSort,
                        limit: '50',
                        mlx_only: this.msMlxOnly,
                    });
                    const response = await fetch(`/admin/api/ms/search?${params}`, { signal: controller.signal });
                    if (response.ok) {
                        const data = await response.json();
                        this.msSearchResults = data.models || [];
                        this.msSearchLoaded = true;
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.msError = data.detail || 'Search failed';
                        setTimeout(() => { this.msError = ''; }, 5000);
                    }
                } catch (err) {
                    if (err.name === 'AbortError') {
                        this.msError = 'ModelScope request timed out. The service may be unavailable.';
                    } else {
                        this.msError = 'Failed to connect to ModelScope.';
                    }
                    setTimeout(() => { this.msError = ''; }, 5000);
                    console.error('MS search failed:', err);
                } finally {
                    clearTimeout(timeoutId);
                    this.msSearchLoading = false;
                }
            },

            mImmediateSearch() {
                const query = this.msSearchQuery.trim();
                if (query) {
                    // Save to search history
                    this.msSearchHistory = [query, ...this.msSearchHistory.filter(h => h !== query)].slice(0, 10);
                    localStorage.setItem('msSearchHistory', JSON.stringify(this.msSearchHistory));
                }
                this.msSearchHistoryOpen = false;
                this.searchMSModels();
            },

            msDebounceSearch() {
                clearTimeout(this.msSearchDebounceTimer);
                this.msSearchDebounceTimer = setTimeout(() => {
                    if (this.msSearchQuery.trim()) {
                        this.searchMSModels();
                    }
                }, 500);
            },

            closeMsSearchHistory() {
                setTimeout(() => { this.msSearchHistoryOpen = false; }, 200);
            },

            selectMsSearchHistory(item) {
                this.msSearchQuery = item;
                this.msSearchHistoryOpen = false;
                this.mImmediateSearch();
            },

            // MS Model detail modal
            async openMsModelDetail(repoId) {
                this.msModelDetailLoading = true;
                this.msModelDetail = null;
                const controller = new Abor   adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        M * N,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }

  qmm_n_impl<T, group_size, bits, BM, BK, BN>(
      w, scales, biases, x, y, Xs, Ws, K, N, M, tid, lid, simd_gid, simd_lid);
}

template <typename T, int group_size, int bits>
[[kernel]] void affine_gather_qmv_fast(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    const device uint32_t* lhs_indices [[buffer(4)]],
    const device uint32_t* rhs_indices [[buffer(5)]],
    device T* y [[buffer(6)]],
    const constant int& in_vec_size [[buffer(7)]],
    const constant int& out_vec_size [[buffer(8)]],
    const constant int& x_batch_ndims [[buffer(9)]],
    const constant int* x_shape [[buffer(10)]],
    const constant int64_t* x_strides [[buffer(11)]],
    const constant int& w_batch_ndims [[buffer(12)]],
    const constant int* w_shape [[buffer(13)]],
    const constant int64_t* w_strides [[buffer(14)]],
    const constant int64_t* s_strides [[buffer(15)]],
    const constant int64_t* b_strides [[buffer(16)]],
    const constant int& batch_ndims [[buffer(17)]],
    const constant int* batch_shape [[buffer(18)]],
    const constant int64_t* lhs_strides [[buffer(19)]],
    const constant int64_t* rhs_strides [[buffer(20)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  int M = x_shape[x_batch_ndims];
  adjust_matrix_offsets<T>(
      x,
      w,
      scales,
      biases,
      lhs_indices,
      rhs_indices,
      y,
      out_vec_size * M,
      batch_ndims,
      batch_shape,
      lhs_strides,
      rhs_strides,
      x_batch_ndims,
      x_shape,
      x_strides,
      w_batch_ndims,
      w_shape,
      w_strides,
      s_strides,
      b_strides,
      tid);
  qmv_fast_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      simd_gid,
      simd_lid);
}

template <typename T, int group_size, int bits>
[[kernel]] void affine_gather_qmv(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    const device uint32_t* lhs_indices [[buffer(4)]],
    const device uint32_t* rhs_indices [[buffer(5)]],
    device T* y [[buffer(6)]],
    const constant int& in_vec_size [[buffer(7)]],
    const constant int& out_vec_size [[buffer(8)]],
    const constant int& x_batch_ndims [[buffer(9)]],
    const constant int* x_shape [[buffer(10)]],
    const constant int64_t* x_strides [[buffer(11)]],
    const constant int& w_batch_ndims [[buffer(12)]],
    const constant int* w_shape [[buffer(13)]],
    const constant int64_t* w_strides [[buffer(14)]],
    const constant int64_t* s_strides [[buffer(15)]],
    const constant int64_t* b_strides [[buffer(16)]],
    const constant int& batch_ndims [[buffer(17)]],
    const constant int* batch_shape [[buffer(18)]],
    const constant int64_t* lhs_strides [[buffer(19)]],
    const constant int64_t* rhs_strides [[buffer(20)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  int M = x_shape[x_batch_ndims];
  adjust_matrix_offsets<T>(
      x,
      w,
      scales,
      biases,
      lhs_indices,
      rhs_indices,
      y,
      out_vec_size * M,
      batch_ndims,
      batch_shape,
      lhs_strides,
      rhs_strides,
      x_batch_ndims,
      x_shape,
      x_strides,
      w_batch_ndims,
      w_shape,
      w_strides,
      s_strides,
      b_strides,
      tid);
  qmv_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      )
        if resp.status_code == 200:
            data = resp.json().get("Data", {})
            return data.get("Models", data.get("models", []))
    except Exception as e:
        logger.warning(f"ModelScope REST API fetch failed: {e}")
    return []


class MSDownloader:
    """Manages ModelScope model downloads with progress tracking.

    Uses modelscope.snapshot_download() for actual downloads and polls
    the target directory size to estimate progress.

    Args:
        model_dir: Directory where downloaded models are stored.
        on_complete: Async callback invoked when a download completes successfully.
    """

    @staticmethod
    async def get_recommended_models(
        max_memory_bytes: int,
        limit: int = 60,
        result_limit: int = 50,
        mlx_only: bool = True,
    ) -> dict:
        """Fetch trending and popular models from ModelScope.

        When mlx_only is True, uses SDK to list models from mlx-community
        organization. When False, uses REST API to search all organizations.

        Args:
            max_memory_bytes: Maximum model size in bytes (typically system memory).
            limit: Number of models to fetch per category.
            result_limit: Maximum number of models to return per category.
            mlx_only: If True, restrict to mlx-community organization.

        Returns:
            Dict with 'trending' and 'popular' lists.
        """

        async def _fetch() -> list[dict]:
            if mlx_only:
                api = _get_ms_api()
                if api is None:
                    logger.warning("ModelScope SDK not available")
                    return []
                try:
                    data = await asyncio.wait_for(
                        asyncio.to_thread(
                            api.list_models,
                            "mlx-community",
                            page_size=limit,
                        ),
                        timeout=_MS_API_TIMEOUT + 5,
                    )
                except Exception as e:
                    logger.warning(f"ModelScope recommended fetch failed: {e}")
                    return []
                models_data = data.get("Models", [])
                if not models_data:
                    models_data = data.get("models", [])
            else:
                models_data = await _fetch_ms_models_rest(page_size=limit)

            results = []
            for entry in models_data:
                m = _parse_ms_model_entry(entry)
                downloads = m.get("downloads", 0)
                size = m.get("size", 0)
                # Filter by minimum downloads
                if downloads < _MIN_DOWNLOADS:
                    continue
                # Filter by memory size (only when list_models already had
                # a size — enrichment may reveal more below).
                if size > 0 and size > max_memory_bytes:
                    continue
                results.append(m)
                if len(results) >= result_limit * 2:
                    break

            return results

        models = await _fetch()

        # Enrich with size + params from per-model config.json / detail
        # fetches. Bounded concurrency keeps the call to ~1–2s for a full
        # page; results are cached in-process so subsequent loads are free.
        if models:
            sem = asyncio.Semaphore(_ENRICH_CONCURRENCY)
            enriched = await asyncio.gather(
                *(_enrich_ms_entry(m, sem) for m in models),
                return_exceptions=True,
            )
            models = [m for m in enriched if isinstance(m, dict)]

            # Re-apply the memory filter now that enrichment may have
            # supplied a real size for entries that list_models reported
            # as 0. Entries that still have no size are kept (better to
            # show with a blank size than hide a candidate the user has
            # enough RAM for).
            models = [
                m for m in models
                if (m.get("size", 0) == 0) or (m["size"] <= max_memor,
                                              comment: "Validation error when min-p falls outside the allowed range")
        }
    }

    static func topK(_ raw: String) -> Result<Int?, SamplingValidationError> {
        let t = raw.trimmingCharacters(in: .whitespaces)
        if t.isEmpty { return .success(nil) }
        guard let v = Int(t) else {
            return .failure(.init(message: String(localized: "settings.validator.top_k.integer",
                                                  defaultValue: "Top K must be an integer.",
                                                  comment: "Validation error when top-k isn't an integer")))
        }
        guard v >= 1 else {
            return .failure(.init(message: String(localized: "settings.validator.top_k.positive",
                                                  defaultValue: "Top K must be a positive integer.",
                                                  comment: "Validation error when top-k isn't positive")))
        }
        return .success(v)
    }

    static func penalty(_ raw: String, name: String) -> Result<Double?, SamplingValidationError> {
        parseDouble(raw, label: name) { v in
            (v >= -2 && v <= 2) ? nil : String(localized: "settings.validator.penalty.range",
                                               defaultValue: "\(name) must be in [-2, 2].",
                                               comment: "Validation error when a penalty field is outside [-2,2]; placeholder is the field name")
        }
    }

    private static func parseDouble(
        _ raw: String,
        label: String,
        check: (Double) -> String?
    ) -> Result<Double?, SamplingValidationError> {
        let t = raw.trimmingCharacters(in: .whitespaces)
        if t.isEmpty { return .success(nil) }
        guard let v = Double(t) else {
            return .failure(.init(message: String(localized: "settings.validator.must_be_number",
                                                  defaultValue: "\(label) must be a number.",
                                                  comment: "Validation error when a sampling field isn't a number; placeholder is the field name")))
        }
        if let msg = check(v) { return .failure(.init(message: msg)) }
        return .success(v)
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/ModelsScreen.swift =====

// PR 8 — Models screen.
//
// Reads `/admin/api/models` (GET) and surfaces it as two sections:
//   • Active Models — currently-loaded engines, with an unload affordance
//   • Model Library — every discovered model on disk; load button + drill
//     into ModelSettingsScreen via the chevron.
//
// Polling at 2 s while visible: load/unload responses are eventual (engine
// pool is async) and we want the row state to converge without manual
// refresh. Drilling into a model sets `services.modelDetailID`, which
// AppView swaps the screen content for.

import SwiftUI

struct ModelsScreen: View {
    @Environment(AppServices.self) private var services
    @State private var vm = ModelsScreenVM()

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            ActiveModelsSection(
                models: vm.activeModels,
                onUnload: { id in vm.unload(id: id, client: services.client) }
            )

            LibrarySection(
                models: vm.libraryModels,
                isModelLoaded: { id in vm.activeModels.contains(where: { $0.id == id }) },
                deletingID: vm.deletingID,
                onLoad: { id in vm.load(id: id, client: services.client) },
                onUnload: { id in vm.unload(id: id, client: services.client) },
                onOpenSettings: { id in services.modelDetailID = id },
                onRequestRemove: { id in vm.pendingRemoveID = id },
                onToggleFavorite: { id, fav in vm.setFavorite(id: id, favorite: fav, client: services.client) }
            )

            if let error = vm.lastError {
                Text(error)
                    .font(.omlxText(11))
                    .foregrtController();
                const timeoutId = setTimeout(() => controller.abort(), 20000);
                try {
                    const params = new URLSearchParams({ model_id: repoId });
                    const response = await fetch(`/admin/api/ms/model-info?${params}`, { signal: controller.signal });
                    if (response.ok) {
                        this.msModelDetail = await response.json();
                    } else if (response.status === 401) {
                        window.location.href = '/admin';
                    } else {
                        const data = await response.json().catch(() => ({}));
                        this.msError = data.detail || 'Failed to fetch model info';
                        setTimeout(() => { this.msError = ''; }, 5000);
                    }
                } catch (err) {
                    if (err.name === 'AbortError') {
                        this.msError = 'ModelScope request timed out. The service may be unavailable.';
                    } else {
                        this.msError = 'Failed to connect to ModelScope.';
                    }
                    setTimeout(() => { this.msError = ''; }, 5000);
                    console.error('Failed to fetch MS model info:', err);
                } finally {
                    clearTimeout(timeoutId);
                    this.msModelDetailLoading = false;
                }
            },
        }
    }


# ===== FILE: omlx/admin/static/js/highlight.min.js =====

/*!
  Highlight.js v11.9.0 (git: f47103d4f1)
  (c) 2006-2023 undefined and other contributors
  License: BSD-3-Clause
 */
var hljs=function(){"use strict";function e(n){
return n instanceof Map?n.clear=n.delete=n.set=()=>{
throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{
throw Error("set is read-only")
}),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{
const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a)
})),n}class n{constructor(e){
void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}
ignoreMatch(){this.isMatchIgnored=!0}}function t(e){
return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")
}function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n]
;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope
;class r{constructor(e,n){
this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){
this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{
if(e.startsWith("language:"))return e.replace("language:","language-")
;if(e.includes(".")){const t=e.split(".")
;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ")
}return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)}
closeNode(e){i(e)&&(this.buffer+="</span>")}value(){return this.buffer}span(e){
this.buffer+=`<span class="${e}">`}}const s=(e={})=>{const n={children:[]}
;return Object.assign(n,e),n};class o{constructor(){
this.rootNode=s(),this.stack=[this.rootNode]}get top(){
return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){
this.top.children.push(e)}openNode(e){const n=s({scope:e})
;this.add(n),this.stack.push(n)}closeNode(){
if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){
for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}
walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){
return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),
n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){
"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{
o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e}
addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){
this.closeNode()}__addSublanguage(e,n){const t=e.root
;n&&(t.scope="language:"+n),this.add(t)}toHTML(){
return new r(this,this.options).value()}finali    tid,
      simd_gid,
      simd_lid);
}

template <typename T, int group_size, int bits>
[[kernel]] void affine_gather_qvm(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    const device uint32_t* lhs_indices [[buffer(4)]],
    const device uint32_t* rhs_indices [[buffer(5)]],
    device T* y [[buffer(6)]],
    const constant int& in_vec_size [[buffer(7)]],
    const constant int& out_vec_size [[buffer(8)]],
    const constant int& x_batch_ndims [[buffer(9)]],
    const constant int* x_shape [[buffer(10)]],
    const constant int64_t* x_strides [[buffer(11)]],
    const constant int& w_batch_ndims [[buffer(12)]],
    const constant int* w_shape [[buffer(13)]],
    const constant int64_t* w_strides [[buffer(14)]],
    const constant int64_t* s_strides [[buffer(15)]],
    const constant int64_t* b_strides [[buffer(16)]],
    const constant int& batch_ndims [[buffer(17)]],
    const constant int* batch_shape [[buffer(18)]],
    const constant int64_t* lhs_strides [[buffer(19)]],
    const constant int64_t* rhs_strides [[buffer(20)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  int M = x_shape[x_batch_ndims];
  adjust_matrix_offsets<T>(
      x,
      w,
      scales,
      biases,
      lhs_indices,
      rhs_indices,
      y,
      out_vec_size * M,
      batch_ndims,
      batch_shape,
      lhs_strides,
      rhs_strides,
      x_batch_ndims,
      x_shape,
      x_strides,
      w_batch_ndims,
      w_shape,
      w_strides,
      s_strides,
      b_strides,
      tid);
  qvm_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      simd_gid,
      simd_lid);
}

template <
    typename T,
    const int group_size,
    const int bits,
    const bool aligned_N,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
[[kernel]] void affine_gather_qmm_t(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    const device uint32_t* lhs_indices [[buffer(4)]],
    const device uint32_t* rhs_indices [[buffer(5)]],
    device T* y [[buffer(6)]],
    const constant int& K [[buffer(7)]],
    const constant int& N [[buffer(8)]],
    const constant int& M [[buffer(9)]],
    const constant int& x_batch_ndims [[buffer(10)]],
    const constant int* x_shape [[buffer(11)]],
    const constant int64_t* x_strides [[buffer(12)]],
    const constant int& w_batch_ndims [[buffer(13)]],
    const constant int* w_shape [[buffer(14)]],
    const constant int64_t* w_strides [[buffer(15)]],
    const constant int64_t* s_strides [[buffer(16)]],
    const constant int64_t* b_strides [[buffer(17)]],
    const constant int& batch_ndims [[buffer(18)]],
    const constant int* batch_shape [[buffer(19)]],
    const constant int64_t* lhs_strides [[buffer(20)]],
    const constant int64_t* rhs_strides [[buffer(21)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  (void)lid;

  constexpr int BK_padded = (BK + 16 / sizeof(T));

  threadgroup T Xs[BM * BK_padded];
  threadgroup T Ws[BN * BK_padded];

  adjust_matrix_offsets<T>(
      x,
      w,
      scales,
      biases,
      lhs_indices,
      rhs_indices,
      y,
      M * N,
      batch_ndims,
      batch_shape,
      lhs_strides,
      rhs_strides,
      x_batch_ndims,
      x_shape,
      x_strides,
      w_batch_ndims,
      w_shape,
      w_strides,
      s_strides,
      b_strides,
      tid);
  qmm_t_impl<T, group_size, bits, aligned_N, BM, BK, BN>(
      w,
      scales,
      biases,
      x,
      y,
      Xs,
      Ws,
      K,
      N,
      M,
      K,
      tid,
      lid,
      simd_gid,
      simd_lid);
y_bytes)
            ]

        # Sort by downloads for popular, keep original order for trending
        trending = models[:result_limit]
        popular = sorted(models, key=lambda x: x.get("downloads", 0), reverse=True)[:result_limit]

        return {
            "trending": trending,
            "popular": popular,
        }

    @staticmethod
    async def search_models(
        query: str,
        sort: str = "trending",
        limit: int = 100,
        mlx_only: bool = True,
    ) -> dict:
        """Search models on ModelScope.

        When mlx_only is True, uses SDK to list models from mlx-community
        and filters by query string. When False, uses REST API to search
        across all organizations.

        Args:
            query: Search query string.
            sort: Sort order (trending/downloads/created/updated).
            limit: Maximum number of results to return.
            mlx_only: If True, restrict to mlx-community organization.

        Returns:
            Dict with 'models' list and 'total' count.
        """
        if mlx_only:
            api = _get_ms_api()
            if api is None:
                logger.warning("ModelScope SDK not available")
                return {"models": [], "total": 0}

            try:
                data = await asyncio.wait_for(
                    asyncio.to_thread(
                        api.list_models,
                        "mlx-community",
                        page_size=200,
                    ),
                    timeout=_MS_API_TIMEOUT + 5,
                )
            except Exception as e:
                logger.error(f"ModelScope search failed: {e}")
                return {"models": [], "total": 0}

            models_data = data.get("Models", [])
            if not models_data:
                models_data = data.get("models", [])
        else:
            models_data = await _fetch_ms_models_rest(
                query=query, page_size=200
            )

        # Filter by query string (case-insensitive)
        query_lower = query.lower()
        filtered = []
        for entry in models_data:
            name = entry.get("Name", "")
            if query_lower in name.lower():
                m = _parse_ms_model_entry(entry)
                filtered.append(m)

        # Sort results
        if sort == "downloads":
            filtered.sort(key=lambda x: x.get("downloads", 0), reverse=True)
        elif sort == "created":
            pass  # Keep original order (newest first by default)
        elif sort == "updated":
            pass  # Keep original order

        # Limit results
        results = filtered[:limit]

        return {
            "models": results,
            "total": len(filtered),
        }

    @staticmethod
    async def get_model_info(model_id: str) -> dict:
        """Fetch detailed model information from ModelScope.

        Args:
            model_id: ModelScope model ID (e.g., "qwen/Qwen2.5-7B-Instruct-MLX").

        Returns:
            Dict with model details including description, files, tags, etc.
        """
        api = _get_ms_api()
        if api is None:
            raise RuntimeError("ModelScope SDK not available")

        # Get model metadata
        model_data = await asyncio.wait_for(
            asyncio.to_thread(api.get_model, model_id),
            timeout=_MS_API_TIMEOUT,
        )

        # get_model may return a string or dict depending on SDK version
        if isinstance(model_data, str):
            import json

            try:
                model_data = json.loads(model_data)
            except (json.JSONDecodeError, TypeError):
                model_data = {}

        if not isinstance(model_data, dict):
            model_data = {}

        # Get file list
        files = []
        total_file_size = 0
        try:
            file_list = await asyncio.wait_for(
                asyncio.to_thread(api.get_model_files, model_id),
                timeout=_MS_API_TIMEOUT,
            )
            for f in file_list or []:
                fname = f.get("Name") or f.get("Path", "oundStyle(.red)
                    .padding(.horizontal, 18)
                    .padding(.top, 8)
            }
        }
        .task { await vm.start(client: services.client) }
        .onDisappear { vm.stop() }
        .confirmationDialog(
            String(localized: "models.delete.confirm_title",
                   defaultValue: "Delete this model from disk?",
                   comment: "Confirmation dialog title shown before deleting a model from disk"),
            isPresented: Binding(
                get: { vm.pendingRemoveID != nil },
                set: { if !$0 { vm.pendingRemoveID = nil } }
            ),
            titleVisibility: .visible,
            presenting: vm.pendingRemoveID
        ) { id in
            Button(String(localized: "models.delete.confirm_button",
                          defaultValue: "Delete \(id)",
                          comment: "Destructive button label inside the delete-model confirmation dialog; placeholder is the model id"),
                   role: .destructive) {
                vm.remove(id: id, client: services.client)
            }
            Button(String(localized: "common.cancel",
                          defaultValue: "Cancel",
                          comment: "Generic cancel button"),
                   role: .cancel) { vm.pendingRemoveID = nil }
        } message: { id in
            Text(String(localized: "models.delete.confirm_message",
                        defaultValue: "The model files will be permanently removed from disk and unloaded if currently running.",
                        comment: "Body text inside the delete-model confirmation dialog explaining the impact"))
        }
    }
}

// MARK: - Active section

private struct ActiveModelsSection: View {
    let models: [ModelDTO]
    let onUnload: (String) -> Void

    @Environment(\.omlxTheme) private var theme

    private var memoryFootprint: Int64 {
        models.reduce(0) { $0 + $1.estimatedSize }
    }

    var body: some View {
        SectionHeader(String(localized: "models.active.title",
                                    defaultValue: "Active Models",
                                    comment: "Section heading for the list of currently-loaded models"),
                      subtitle: String(localized: "models.active.subtitle",
                                       defaultValue: "\(models.count) loaded · \(formatBytes(memoryFootprint))",
                                       comment: "Subtitle for the Active Models section. Placeholders: count of loaded models, total memory footprint"))

        ListGroup {
            if models.isEmpty {
                FreeRow(isLast: true) {
                    Text(String(localized: "models.active.empty",
                                defaultValue: "No models loaded",
                                comment: "Empty-state message shown when no models are currently loaded"))
                        .font(.omlxText(12))
                        .foregroundStyle(theme.textTertiary)
                        .frame(maxWidth: .infinity, alignment: .center)
                        .padding(.vertical, 14)
                }
            } else {
                ForEach(Array(models.enumerated()), id: \.element.id) { idx, m in
                    FreeRow(isLast: idx == models.count - 1) {
                        HStack(spacing: 10) {
                            if m.pinned == true {
                                Image(systemName: "pin.fill")
                                    .font(.system(size: 11))
                                    .foregroundStyle(theme.textSecondary)
                            }
                            Text(m.displayTitle)
                                .font(.omlxText(13, weight: .medium))
                                .foregroundStyle(theme.text)
                                .lineLimit(1)
                                .truncationMode(.middle)
                            Spacer(minLength: 8)
                            ActiveBadge(model: m)
                            Text(m.estimatedSizeFormatted ?? formatBytesze(){
return this.closeAllNodes(),!0}}function c(e){
return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")}
function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")}
function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{
const n=e[e.length-1]
;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{}
})(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"}
function p(e){return RegExp(e.toString()+"|").exec("").length-1}
const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./
;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t
;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break}
i+=a.substring(0,e.index),
a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0],
"("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)}
const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={
begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'",
illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n",
contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n,
contains:[]},t);i.contains.push({scope:"doctag",
begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",
end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0})
;const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/)
;return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i
},M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({
__proto__:null,APOS_STRING_MODE:O,BACKSLASH_ESCAPE:v,BINARY_NUMBER_MODE:{
scope:"number",begin:w,relevance:0},BINARY_NUMBER_RE:w,COMMENT:x,
C_BLOCK_COMMENT_MODE:S,C_LINE_COMMENT_MODE:M,C_NUMBER_MODE:{scope:"number",
begin:N,relevance:0},C_NUMBER_RE:N,END_SAME_AS_BEGIN:e=>Object.assign(e,{
"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{
n.data._beginMatch!==e[1]&&n.ignoreMatch()}}),HASH_COMMENT_MODE:A,IDENT_RE:f,
MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0},
NUMBER_MODE:{scope:"number",begin:y,relevance:0},NUMBER_RE:y,
PHRASAL_WORDS_MODE:{
begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
},QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/,
end:/\/[gimuy]*/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]},
RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",
SHEBANG:(e={})=>{const n=/^#![ ]*\//
;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n,
end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},
TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_IDENT_RE:E,
UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0}});function T(e,n){
"."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){
void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){
n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",
e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,
void 0===e.relevance&&(e.relevance=0))}function I(e,n){
Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){
if(e.match){
if(e.begin||e.end)throw Error("begin & end are not supported with match")
;e.begin=e.match,delete e.match}}function B(e,n){
void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return
;if(e.starts)throw Error("beforeMatch cannot be used with starts")
;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n]
})),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={
relevance:0,contains:[Object.assign(t,{endsParent:!0})]
},e.relevance=0,delete t.beforeMatch
}

template <
    typename T,
    const int group_size,
    const int bits,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
[[kernel]] void affine_gather_qmm_n(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    const device uint32_t* lhs_indices [[buffer(4)]],
    const device uint32_t* rhs_indices [[buffer(5)]],
    device T* y [[buffer(6)]],
    const constant int& K [[buffer(7)]],
    const constant int& N [[buffer(8)]],
    const constant int& M [[buffer(9)]],
    const constant int& x_batch_ndims [[buffer(10)]],
    const constant int* x_shape [[buffer(11)]],
    const constant int64_t* x_strides [[buffer(12)]],
    const constant int& w_batch_ndims [[buffer(13)]],
    const constant int* w_shape [[buffer(14)]],
    const constant int64_t* w_strides [[buffer(15)]],
    const constant int64_t* s_strides [[buffer(16)]],
    const constant int64_t* b_strides [[buffer(17)]],
    const constant int& batch_ndims [[buffer(18)]],
    const constant int* batch_shape [[buffer(19)]],
    const constant int64_t* lhs_strides [[buffer(20)]],
    const constant int64_t* rhs_strides [[buffer(21)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  (void)lid;

  constexpr int BK_padded = (BK + 16 / sizeof(T));
  constexpr int BN_padded = (BN + 16 / sizeof(T));

  threadgroup T Xs[BM * BK_padded];
  threadgroup T Ws[BK * BN_padded];

  adjust_matrix_offsets<T>(
      x,
      w,
      scales,
      biases,
      lhs_indices,
      rhs_indices,
      y,
      M * N,
      batch_ndims,
      batch_shape,
      lhs_strides,
      rhs_strides,
      x_batch_ndims,
      x_shape,
      x_strides,
      w_batch_ndims,
      w_shape,
      w_strides,
      s_strides,
      b_strides,
      tid);
  qmm_n_impl<T, group_size, bits, BM, BK, BN>(
      w, scales, biases, x, y, Xs, Ws, K, N, M, tid, lid, simd_gid, simd_lid);
}

template <
    typename T,
    int group_size,
    int bits,
    int BM,
    int BN,
    int BK,
    int WM,
    int WN,
    bool transpose>
[[kernel]] void affine_gather_qmm_rhs(
    const device T* x [[buffer(0)]],
    const device uint32_t* w [[buffer(1)]],
    const device T* scales [[buffer(2)]],
    const device T* biases [[buffer(3)]],
    const device uint32_t* indices [[buffer(4)]],
    device T* y [[buffer(5)]],
    const constant int& M [[buffer(6)]],
    const constant int& N [[buffer(7)]],
    const constant int& K [[buffer(8)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_group_id [[simdgroup_index_in_threadgroup]],
    uint simd_lane_id [[thread_index_in_simdgroup]]) {
  constexpr int pack_factor = get_pack_factor<bits, 8>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();
  constexpr int BK_padded = (BK + 16 / sizeof(T));
  constexpr int BN_padded = (BN + 16 / sizeof(T));

  using mma_t = mlx::steel::BlockMMA<
      T,
      T,
      BM,
      BN,
      BK,
      WM,
      WN,
      false,
      transpose,
      BK_padded,
      transpose ? BK_padded : BN_padded>;
  using loader_x_t =
      mlx::steel::BlockLoader<T, BM, BK, BK_padded, 1, WM * WN * SIMD_SIZE>;
  using loader_w_t = QuantizedBlockLoader<
      T,
      transpose ? BN : BK,
      transpose ? BK : BN,
      transpose ? BK_padded : BN_padded,
      transpose,
      WM * WN * SIMD_SIZE,
      group_size,
      bits>;

  threadgroup T Xs[BM * BK_padded];
  threadgroup T Ws[transpose ? BN * BK_padded : BK * BN_padded];

  // Compute the block
  const int K_w = K * bytes_per_pack / pack_factor;
  const int K_g = K / group_size;
  const int N_w = N * bytes_per_pack / pack_factor;
  const int N_g = N / group_size;
  const int K_it = K / BK;
  const size_t stride_w = transpose ? N * K_w : K * N_w;
  const size_t stride_s = transpose ? N * K_g : K * N_g;
  const int y_row = tid.y * BM;
  const int y_col = tid.x * BN;
  const size_t y_row")
                fsize = f.get("Size") or 0
                if isinstance(fsize, str):
                    try:
                        fsize = int(fsize)
                    except ValueError:
                        fsize = 0
                total_file_size += fsize
                files.append(
                    {
                        "name": fname,
                        "size": fsize,
                        "size_formatted": (
                            _format_model_size(fsize) if fsize > 0 else ""
                        ),
                    }
                )
        except Exception as e:
            logger.warning(f"Could not fetch file list for {model_id}: {e}")

        # Fetch model card (README.md) content
        model_card = ""
        try:
            endpoint = _get_ms_endpoint()
            readme_url = f"{endpoint}/api/v1/models/{model_id}/repo?FilePath=README.md&Revision=master"
            resp = await asyncio.wait_for(
                asyncio.to_thread(
                    requests.get,
                    readme_url,
                    timeout=_MS_API_TIMEOUT,
                ),
                timeout=_MS_API_TIMEOUT + 5,
            )
            if resp.status_code == 200:
                card_text = resp.text
                # Strip YAML front matter (between --- markers)
                if card_text.startswith("---"):
                    end = card_text.find("---", 3)
                    if end != -1:
                        card_text = card_text[end + 3:].strip()
                model_card = card_text
        except Exception:
            pass  # README not available

        # Extract metadata
        name = model_data.get("Name") or model_id
        downloads = model_data.get("Downloads") or 0
        likes = model_data.get("Likes") or model_data.get("Stars") or 0
        tags = model_data.get("Tags") or []
        if isinstance(tags, str):
            tags = [t.strip() for t in tags.split(",") if t.strip()]

        return {
            "repo_id": model_id,
            "name": name,
            "model_card": model_card,
            "description": model_data.get("Description", ""),
            "files": files,
            "tags": tags,
            "pipeline_tag": model_data.get("Task", ""),
            "params": None,
            "params_formatted": None,
            "size": total_file_size,
            "size_formatted": (
                _format_model_size(total_file_size) if total_file_size > 0 else ""
            ),
            "downloads": downloads,
            "likes": likes,
            "created_at": model_data.get("CreatedTime", ""),
            "updated_at": model_data.get("LastUpdatedTime", ""),
        }

    def __init__(
        self,
        model_dir: str,
        on_complete: Optional[Callable] = None,
    ):
        self._model_dir = Path(model_dir)
        self._tasks: dict[str, DownloadTask] = {}
        self._active_tasks: dict[str, asyncio.Task] = {}
        self._progress_tasks: dict[str, asyncio.Task] = {}
        self._on_complete = on_complete
        self._cancelled: set[str] = set()
        self._download_sem = asyncio.Semaphore(1)

    @property
    def model_dir(self) -> Path:
        return self._model_dir

    def update_model_dir(self, new_dir: str) -> None:
        """Update the model directory path."""
        self._model_dir = Path(new_dir)

    async def start_download(
        self, model_id: str, ms_token: str = ""
    ) -> DownloadTask:
        """Start downloading a model from ModelScope.

        Args:
            model_id: ModelScope model ID (e.g., "qwen/Qwen2.5-7B-Instruct-MLX").
            ms_token: Optional ModelScope token for private models.

        Returns:
            The created DownloadTask.

        Raises:
            ValueError: If model_id format is invalid or download is already queued.
            RuntimeError: If ModelScope SDK is not installed.
        """
        if not MS_SDK_AVAILABLE:
            raise RuntimeError(
                "ModelScope SDK not installed. "
                "Install with: pip install \"oml(m.estimatedSize))
                                .font(.omlxMono(11))
                                .foregroundStyle(theme.textSecondary)
                                .frame(minWidth: 60, alignment: .trailing)
                            Button {
                                onUnload(m.id)
                            } label: {
                                Image(systemName: "eject")
                                    .font(.system(size: 12))
                            }
                            .buttonStyle(.omlx(.plain, size: .small))
                            .help(String(localized: "models.active.unload.help",
                                         defaultValue: "Unload model",
                                         comment: "Tooltip on the eject button that unloads an active model"))
                        }
                    }
                }
            }
        }
    }
}

private struct ActiveBadge: View {
    let model: ModelDTO
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        if model.isLoading {
            StatusPill(status: .starting)
        } else if model.loaded {
            StatusPill(status: .custom(color: theme.greenDot,
                                       label: String(localized: "models.active.badge.loaded",
                                                     defaultValue: "Loaded",
                                                     comment: "Status pill label for a model that is currently loaded in memory"),
                                       fillBg: true))
        } else {
            StatusPill(status: .custom(color: theme.textTertiary,
                                       label: String(localized: "models.active.badge.idle",
                                                     defaultValue: "Idle",
                                                     comment: "Status pill label for a model that is not currently loaded"),
                                       fillBg: true))
        }
    }
}

// MARK: - Library section

private struct LibrarySection: View {
    let models: [ModelDTO]
    let isModelLoaded: (String) -> Bool
    let deletingID: String?
    let onLoad: (String) -> Void
    let onUnload: (String) -> Void
    let onOpenSettings: (String) -> Void
    let onRequestRemove: (String) -> Void
    let onToggleFavorite: (String, Bool) -> Void

    @Environment(\.omlxTheme) private var theme

    private var totalSize: Int64 {
        models.reduce(0) { $0 + $1.estimatedSize }
    }

    var body: some View {
        SectionHeader(String(localized: "models.library.title",
                                    defaultValue: "Model Library",
                                    comment: "Section heading for the on-disk model library"),
                      subtitle: String(localized: "models.library.subtitle",
                                       defaultValue: "Models: \(models.count) · \(formatBytes(totalSize)) on disk",
                                       comment: "Subtitle for the Model Library section. Placeholders: model count, total bytes on disk"))

        ListGroup {
            if models.isEmpty {
                FreeRow(isLast: true) {
                    VStack(spacing: 6) {
                        Text(String(localized: "models.library.empty.title",
                                    defaultValue: "No models discovered",
                                    comment: "Empty-state title shown when no models have been discovered on disk"))
                            .font(.omlxText(12))
                            .foregroundStyle(theme.textTertiary)
                        Text(String(localized: "models.library.empty.sub",
                                    defaultValue: "Use the Downloads screen to fetch a model from Hugging Face.",
                                    comment: "Empty-state subtitle directing the user to the Downloads screen"))
                            .font(.omlxText(11))
                            .foregroundStyle(theme.textTertiary)
                    }
                    .frame(m},z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword"
;function U(e,n,t=F){const a=Object.create(null)
;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{
Object.assign(a,U(e[t],n,t))})),a;function i(e,t){
n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|")
;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){
return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{
console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{
P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0)
},G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={}
;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1])
;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{
e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope,
delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={
_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope
}),(e=>{if(Array.isArray(e.begin)){
if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),
G
;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"),
G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{
if(Array.isArray(e.end)){
if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"),
G
;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"),
G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){
function n(n,t){
return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":""))
}class t{constructor(){
this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}
addRule(e,n){
n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),
this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null)
;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|"
}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex
;const n=this.matcherRe.exec(e);if(!n)return null
;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t]
;return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){
this.rules=[],this.multiRegexes=[],
this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){
if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t
;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))),
n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){
return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){
this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){
const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex
;let t=n.exec(e)
;if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{
const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)}
return t&&(this.regexIndex+=t.position+1,
this.regexIndex===this.count&&this.considerAll()),t}}
if(e.compilerExtensions||(e.compilerExtensions=[]),
e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language.  See documentation.")
;return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r
;if(r.isCompiled)return o
;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))),
r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null
;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords),
l=r.keywords.$pattern,
delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)),
o.keywordPatternRe=n(l,!0),
s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/),
r.end&&(o.endRe=n(o.end)),
o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)),
r.illegal&&(o.illegal_long = size_t(y_row);
  const size_t y_col_long = size_t(y_col);

  // Prepare threadgroup bounds
  const short tgp_bm = align_M ? BM : short(min(BM, M - y_row));
  const short tgp_bn = align_N ? BN : short(min(BN, N - y_col));

  // Calculate the final tiles in the case that K is not aligned
  const int k_remain = K - K_it * BK;
  const short2 tile_x = short2(k_remain, tgp_bm);
  const short2 tile_w =
      transpose ? short2(k_remain, tgp_bn) : short2(tgp_bn, k_remain);

  // Move x and output to the correct block
  auto wl = (const device uint8_t*)w;
  x += y_row_long * K;
  y += y_row_long * N + y_col_long;
  wl += transpose ? y_col_long * K_w : y_col * bytes_per_pack / pack_factor;
  scales += transpose ? y_col_long * K_g : y_col / group_size;
  biases += transpose ? y_col_long * K_g : y_col / group_size;

  // Do as many matmuls as necessary
  uint32_t index;
  short offset;
  uint32_t index_next = indices[y_row];
  short offset_next = 0;
  int n = 0;
  while (n < tgp_bm) {
    n++;
    offset = offset_next;
    index = index_next;
    offset_next = tgp_bm;
    for (; n < tgp_bm; n++) {
      if (indices[y_row + n] != index) {
        offset_next = n;
        index_next = indices[y_row + n];
        break;
      }
    }
    threadgroup_barrier(mem_flags::mem_none);

    // Prepare threadgroup mma operation
    thread mma_t mma_op(simd_group_id, simd_lane_id);

    // Prepare threadgroup loading operations
    thread loader_x_t loader_x(x, K, Xs, simd_group_id, simd_lane_id);
    thread loader_w_t loader_w(
        wl + index * stride_w,
        scales + index * stride_s,
        biases + index * stride_s,
        transpose ? K : N,
        Ws,
        simd_group_id,
        simd_lane_id);

    // Matrices are all aligned check nothing
    if (align_M && align_N) {
      gemm_loop_aligned(Xs, Ws, mma_op, loader_x, loader_w, K_it);
      if (!align_K) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        gemm_loop_finalize(Xs, Ws, mma_op, loader_x, loader_w, tile_x, tile_w);
      }

      // Store results to device memory
      if (offset_next - offset == BM) {
        mma_op.store_result(y, N);
      } else {
        mma_op.store_result_slice(
            y, N, short2(0, offset), short2(BN, offset_next));
      }
    } else {
      // Tile aligned so check outside of the hot loop
      if ((align_M || tgp_bm == BM) && (align_N || tgp_bn == BN)) {
        gemm_loop_aligned(Xs, Ws, mma_op, loader_x, loader_w, K_it);
        if (!align_K) {
          threadgroup_barrier(mem_flags::mem_threadgroup);
          gemm_loop_finalize(
              Xs, Ws, mma_op, loader_x, loader_w, tile_x, tile_w);
        }

        // Store results to device memory
        if (offset_next - offset == BM) {
          mma_op.store_result(y, N);
        } else {
          mma_op.store_result_slice(
              y, N, short2(0, offset), short2(BN, offset_next));
        }
      }

      // Tile partially aligned check rows
      else if (align_N || tgp_bn == BN) {
        gemm_loop_unaligned<false, true, transpose>(
            Xs, Ws, mma_op, loader_x, loader_w, K_it, tgp_bm, tgp_bn, BK);
        if (!align_K) {
          threadgroup_barrier(mem_flags::mem_threadgroup);
          gemm_loop_finalize(
              Xs, Ws, mma_op, loader_x, loader_w, tile_x, tile_w);
        }
        mma_op.store_result_slice(
            y, N, short2(0, offset), short2(BN, offset_next));
      }

      // Tile partially aligned check cols
      else if (align_M || tgp_bm == BM) {
        gemm_loop_unaligned<true, false, transpose>(
            Xs, Ws, mma_op, loader_x, loader_w, K_it, tgp_bm, tgp_bn, BK);
        if (!align_K) {
          threadgroup_barrier(mem_flags::mem_threadgroup);
          gemm_loop_finalize(
              Xs, Ws, mma_op, loader_x, loader_w, tile_x, tile_w);
        }
        mma_op.store_result_slice(
            y, N, short2(0, offset), short2(tgp_bn, offset_next));
      }

      // Nothing aligned so check both rows and cols
      else {
        gemm_loop_unaligned<false, false, transpose>(
            Xs, Ws, mma_x[modelscope]\""
            )

        model_id = model_id.strip()
        if "/" not in model_id or len(model_id.split("/")) != 2:
            raise ValueError(
                f"Invalid model ID: '{model_id}'. "
                "Expected format: 'owner/model' (e.g., 'qwen/Qwen2.5-7B-Instruct-MLX')"
            )

        # Check for duplicate active downloads
        for task in self._tasks.values():
            if task.repo_id == model_id and task.status in (
                DownloadStatus.PENDING,
                DownloadStatus.DOWNLOADING,
            ):
                raise ValueError(
                    f"Download for '{model_id}' is already in progress"
                )

        task_id = str(uuid.uuid4())
        task = DownloadTask(task_id=task_id, repo_id=model_id)
        self._tasks[task_id] = task

        # Start download in background
        self._active_tasks[task_id] = asyncio.create_task(
            self._run_download(task_id, ms_token)
        )

        logger.info(f"MS Download queued: {model_id} (task_id={task_id})")
        return task

    async def cancel_download(self, task_id: str) -> bool:
        """Cancel an active download.

        Note: Due to Python threading limitations, the actual download thread
        cannot be interrupted immediately. The download will be marked as
        cancelled and files will be cleaned up when the thread completes.

        Args:
            task_id: The task ID to cancel.

        Returns:
            True if the task was found and cancelled.
        """
        task = self._tasks.get(task_id)
        if task is None:
            return False

        if task.status not in (DownloadStatus.PENDING, DownloadStatus.DOWNLOADING):
            return False

        # Mark as cancelled - the running thread will check this flag
        self._cancelled.add(task_id)
        task.status = DownloadStatus.CANCELLED
        task.error = "Cancellation requested. Download will stop shortly."

        # Stop progress polling
        progress_task = self._progress_tasks.pop(task_id, None)
        if progress_task and not progress_task.done():
            progress_task.cancel()

        # Cancel the download task
        active_task = self._active_tasks.pop(task_id, None)
        if active_task and not active_task.done():
            active_task.cancel()

        logger.info(f"MS Download cancelled: {task.repo_id} (task_id={task_id})")
        return True

    def remove_task(self, task_id: str) -> bool:
        """Remove a completed, failed, or cancelled task from the list.

        Args:
            task_id: The task ID to remove.

        Returns:
            True if the task was found and removed.
        """
        task = self._tasks.get(task_id)
        if task is None:
            return False

        if task.status in (DownloadStatus.PENDING, DownloadStatus.DOWNLOADING):
            return False

        del self._tasks[task_id]
        self._cancelled.discard(task_id)
        return True

    async def retry_download(
        self, task_id: str, ms_token: str = ""
    ) -> DownloadTask:
        """Retry a failed or cancelled download, resuming from existing files.

        Args:
            task_id: The task ID of the failed/cancelled download.
            ms_token: Optional ModelScope token for private models.

        Returns:
            The new DownloadTask.

        Raises:
            ValueError: If task not found or not in retryable state.
        """
        old_task = self._tasks.get(task_id)
        if old_task is None:
            raise ValueError(f"Task not found: {task_id}")

        if old_task.status not in (DownloadStatus.FAILED, DownloadStatus.CANCELLED):
            raise ValueError(
                f"Task {task_id} is not retryable (status: {old_task.status.value})"
            )

        model_id = old_task.repo_id
        old_retry_count = old_task.retry_count

        # Remove old task entry
        del self._tasks[task_id]
        self._cancelled.discard(task_id)

        # Start fresh download (snapshot_download resumes from existing faxWidth: .infinity, alignment: .center)
                    .padding(.vertical, 16)
                }
            } else {
                ForEach(Array(models.enumerated()), id: \.element.id) { idx, m in
                    FreeRow(isLast: idx == models.count - 1) {
                        HStack(spacing: 10) {
                            Button {
                                onToggleFavorite(m.id, !(m.isFavorite ?? false))
                            } label: {
                                Image(systemName: (m.isFavorite ?? false) ? "star.fill" : "star")
                                    .font(.system(size: 12))
                                    .foregroundStyle((m.isFavorite ?? false) ? Color.yellow : theme.textTertiary)
                            }
                            .buttonStyle(.plain)
                            .help((m.isFavorite ?? false)
                                ? String(localized: "models.library.favorite_on.help",
                                         defaultValue: "Favorite — click to remove",
                                         comment: "Tooltip on the filled star that removes a model from favorites")
                                : String(localized: "models.library.favorite_off.help",
                                         defaultValue: "Add to favorites",
                                         comment: "Tooltip on the outlined star that adds a model to favorites"))
                            Squircle(systemSymbol: iconName(for: m),
                                     size: 26,
                                     gradient: gradient(for: m))
                            VStack(alignment: .leading, spacing: 2) {
                                HStack(spacing: 4) {
                                    Text(m.displayTitle)
                                        .font(.omlxText(13, weight: .medium))
                                        .foregroundStyle(theme.text)
                                        .lineLimit(1)
                                        .truncationMode(.tail)
                                    CopyIconButton(value: m.id)
                                }
                                Text("\(m.id) · \(m.estimatedSizeFormatted ?? formatBytes(m.estimatedSize))")
                                    .font(.omlxMono(11))
                                    .foregroundStyle(theme.textSecondary)
                                    .lineLimit(1)
                                    .truncationMode(.middle)
                            }
                            Spacer(minLength: 8)
                            HStack(spacing: 10) {
                                if isModelLoaded(m.id) {
                                    Button {
                                        onUnload(m.id)
                                    } label: {
                                        Text(String(localized: "models.library.unload",
                                                    defaultValue: "Unload",
                                                    comment: "Button label that unloads a library model from memory"))
                                            .lineLimit(1)
                                            .frame(minWidth: 48)
                                    }
                                    .buttonStyle(.omlx(.plain, size: .small))
                                } else {
                                    Button {
                                        onLoad(m.id)
                                    } label: {
                                        Text(String(localized: "models.library.load",
                                                    defaultValue: "Load",
                                                    comment: "Button label that loads a library model into memory"))
                                            .lineLimit(1)
                                            .frame(minWidth: 48)
                                    }
                                    .buttonStyle(.omlx(.normal, size: .small))
                 Re=n(r.illegal)),
r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{
variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{
starts:e.starts?a(e.starts):null
}):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o)
})),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i
;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin"
}))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end"
}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){
return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{
constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}}
const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{
const a=Object.create(null),i=Object.create(null),r=[];let s=!0
;const o="Could not find the language '{}', did you forget to load/include a language module?",c={
disableAutodetect:!0,name:"Plain text",contains:[]};let p={
ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,
languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",
cssSelector:"pre code",languages:null,__emitter:l};function _(e){
return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i=""
;"object"==typeof n?(a=e,
t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."),
q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),
i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r)
;const s=r.result?r.result:f(r.language,r.code,t)
;return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){
const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A)
;let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t=""
;for(;n;){t+=A.substring(e,n.index)
;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){
const[e,a]=r
;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{
const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0]
;e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a
;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{
if(""===A)return;let e=null;if("string"==typeof x.subLanguage){
if(!a[x.subLanguage])return void S.addText(A)
;e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top
}else e=E(A,x.subLanguage.length?x.subLanguage:null)
;x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language)
})():c(),A=""}function g(e,n){
""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1
;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue}
const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}}
function b(e,n){
return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope),
e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),
A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{
value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n)
;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e)
;e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){
for(;e.endsParent&&e.parent;)e=e.parent;return e}}
if(e.endsWithParent)return m(e.parent,t,a)}function _(e){
return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){
const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x
;x.endScope&&x.endScope._wrap?(d(),
g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(),
u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n),
d(),r.excludeEnd&&(A=n));do{
x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent
}while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length}
let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0
;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){
if(A+=t.slice(r.index,r.index+op, loader_x, loader_w, K_it, tgp_bm, tgp_bn, BK);
        if (!align_K) {
          threadgroup_barrier(mem_flags::mem_threadgroup);
          gemm_loop_finalize(
              Xs, Ws, mma_op, loader_x, loader_w, tile_x, tile_w);
        }
        mma_op.store_result_slice(
            y, N, short2(0, offset), short2(tgp_bn, offset_next));
      }
    }
  }
}

template <typename T, const int group_size, const int bits>
[[kernel]] void affine_quantize(
    const device T* w [[buffer(0)]],
    device uint8_t* out [[buffer(1)]],
    device T* scales [[buffer(2)]],
    device T* biases [[buffer(3)]],
    uint2 index [[thread_position_in_grid]],
    uint2 grid_dim [[threads_per_grid]]) {
  constexpr float eps = 1e-7;
  constexpr int simd_size = 32;
  constexpr float n_bins = (1 << bits) - 1;
  constexpr int pack_factor = get_pack_factor<bits, 8>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();
  constexpr int values_per_reduce = group_size / simd_size;
  constexpr int writes_per_reduce = pack_factor / values_per_reduce;
  constexpr int writes_per_pack =
      writes_per_reduce > 1 ? 1 : values_per_reduce / pack_factor;
  constexpr int power_of_2_bits = (bits & (bits - 1)) == 0;

  static_assert(
      group_size % simd_size == 0,
      "Group size must be divisible by simd size.");

  size_t offset = index.x + grid_dim.x * size_t(index.y);
  size_t in_index = offset * values_per_reduce;
  size_t out_index = power_of_2_bits
      ? offset * writes_per_pack
      : offset * bytes_per_pack / writes_per_reduce;

  float w_thread[values_per_reduce];
  float w_min = Limits<T>::max;
  float w_max = 0;

#pragma clang loop unroll(full)
  for (int i = 0; i < values_per_reduce; i++) {
    float val = w[in_index + i];
    w_thread[i] = val;
    w_min = min(w_min, val);
    w_max = max(w_max, val);
  }

  w_min = simd_min(w_min);
  w_max = simd_max(w_max);

  float scale;
  float bias;

  if (bits == 1) {
    // Affine 1-bit: bit 0 -> w_min, bit 1 -> w_max
    scale = max(w_max - w_min, eps);
    bias = w_min;
  } else {
    scale = max((w_max - w_min) / n_bins, eps);
    bool side = abs(w_min) > abs(w_max);
    scale = side ? scale : -scale;
    float edge = side ? w_min : w_max;
    float q0 = round(edge / scale);
    bool at_zero = q0 == 0.0f;
    scale = at_zero ? scale : edge / q0;
    bias = at_zero ? 0 : edge;
  }

  // Write out the scales and biases
  size_t gindex = in_index / group_size;
  if (in_index % group_size == 0) {
    scales[gindex] = static_cast<T>(scale);
    biases[gindex] = static_cast<T>(bias);
  }

  using OutType = metal::conditional_t<bits == 5, uint64_t, uint32_t>;
  OutType output = 0;

#pragma clang loop unroll(full)
  for (int i = 0; i < values_per_reduce; i++) {
    uint8_t val = min(round((w_thread[i] - bias) / scale), n_bins);
    if (bits == 8) {
      output = val;
    } else {
      output |= val << (bits * (i % pack_factor));
    }

    if (pack_factor < values_per_reduce && i % pack_factor == pack_factor - 1) {
      out[out_index + i / pack_factor] = output;
      output = 0;
    } else {
#pragma clang loop unroll(full)
      for (int j = 1; j < writes_per_reduce; j++) {
        uint8_t sval = simd_shuffle_down(val, j);
        output |= static_cast<OutType>(sval)
            << (bits * (j * values_per_reduce + i));
      }
    }
  }
  if (bits == 3 || bits == 6) {
    if (in_index % pack_factor == 0 && out_index % bytes_per_pack == 0) {
      out[out_index] = output & 0xff;
      out[out_index + 1] = (output & 0xff00) >> 8;
      out[out_index + 2] = (output & 0xff0000) >> 16;
    }
  } else if (bits == 5) {
    if (in_index % pack_factor == 0 && out_index % bytes_per_pack == 0) {
      out[out_index] = output & 0xff;
      out[out_index + 1] = (output & 0xff00) >> 8;
      out[out_index + 2] = (output & 0xff0000) >> 16;
      out[out_index + 3] = (output & 0xff000000) >> 24;
      out[out_index + 4] = (output & 0xff00000000) >> 32;
    }
  } else {
    if (writes_per_reduce > 0 && out_index % writes_per_reduce == 0) {
      out[out_index / writes_per_reduce] = output;
    }
  }
}
iles)
        new_task = await self.start_download(model_id, ms_token)
        new_task.retry_count = old_retry_count + 1
        return new_task

    def get_tasks(self) -> list[dict]:
        """Return all tasks as serializable dicts, ordered by creation time."""
        return [
            task.to_dict()
            for task in sorted(self._tasks.values(), key=lambda t: t.created_at)
        ]

    async def shutdown(self) -> None:
        """Cancel all active downloads and clean up."""
        # Cancel all progress polling tasks
        for task_id, progress_task in list(self._progress_tasks.items()):
            if not progress_task.done():
                progress_task.cancel()
        self._progress_tasks.clear()

        # Cancel all active download tasks
        for task_id, active_task in list(self._active_tasks.items()):
            if not active_task.done():
                active_task.cancel()
                task = self._tasks.get(task_id)
                if task and task.status == DownloadStatus.DOWNLOADING:
                    task.status = DownloadStatus.CANCELLED
        self._active_tasks.clear()

        logger.info("MS Downloader shut down")

    async def _run_download(self, task_id: str, ms_token: str) -> None:
        """Execute a download task.

        Waits for the download semaphore (only one download runs at a time),
        then fetches file info for total size and runs snapshot_download in a
        thread while polling the target directory for progress updates.
        """
        task = self._tasks[task_id]

        try:
            async with self._download_sem:
                # Check if cancelled while waiting in queue
                if task_id in self._cancelled:
                    return

                task.status = DownloadStatus.DOWNLOADING
                task.started_at = time.time()

                # Preserve {owner}/{model} layout to match other tools
                # (LMStudio, huggingface-cli) and avoid duplicate downloads
                # when sharing a model directory.
                target_dir = self._model_dir / task.repo_id

                # Get total file size for progress estimation
                try:
                    api = _get_ms_api()
                    if api:
                        file_list = await asyncio.wait_for(
                            asyncio.to_thread(api.get_model_files, task.repo_id),
                            timeout=_MS_API_TIMEOUT,
                        )
                        if file_list:
                            task.total_size = _extract_model_size_from_files(
                                file_list
                            )
                except Exception as e:
                    logger.warning(
                        f"Could not fetch file info for {task.repo_id}: {e}. "
                        "Progress estimation will be unavailable."
                    )

                # Start progress polling
                self._progress_tasks[task_id] = asyncio.create_task(
                    self._poll_progress(task_id, target_dir)
                )

                # Build download kwargs
                dl_kwargs = {
                    "model_id": task.repo_id,
                    "local_dir": str(target_dir),
                }
                if ms_token:
                    dl_kwargs["token"] = ms_token

                # Run snapshot_download in a thread (blocking call)
                # Note: Thread cannot be interrupted, cancellation is checked after completion
                await asyncio.to_thread(
                    ms_snapshot_download,
                    **dl_kwargs,
                )

                # Check if cancelled while downloading - clean up downloaded files
                if task_id in self._cancelled:
                    logger.info(
                        f"MS Download was cancelled during execution: {task.repo_id}. "
                        "Cleaning up downloaded files..."
                    )
                    if target_dir.exists():
                        try:
                                  .disabled(m.isLoading)
                                }
                                Button {
                                    onOpenSettings(m.id)
                                } label: {
                                    Image(systemName: "chevron.right")
                                        .font(.system(size: 11))
                                }
                                .buttonStyle(.omlx(.plain, size: .small))
                                .help(String(localized: "models.library.settings.help",
                                             defaultValue: "Settings",
                                             comment: "Tooltip on the chevron that opens a model's settings screen"))
                                Button {
                                    onRequestRemove(m.id)
                                } label: {
                                    if deletingID == m.id {
                                        ProgressView()
                                            .controlSize(.mini)
                                    } else {
                                        Image(systemName: "trash")
                                            .font(.system(size: 11))
                                            .foregroundStyle(theme.redDot)
                                    }
                                }
                                .buttonStyle(.omlx(.plain, size: .small))
                                .disabled(deletingID != nil)
                                .help(String(localized: "models.library.remove.help",
                                             defaultValue: "Remove from disk",
                                             comment: "Tooltip on the trash button that deletes a model from local storage"))
                            }
                            .fixedSize(horizontal: true, vertical: false)
                            .layoutPriority(1)
                        }
                    }
                }
            }
        }
    }

    private func gradient(for m: ModelDTO) -> [Color] {
        switch m.modelType {
        case "embedding", "reranker": return SquircleGradient.downloads
        case "audio_stt", "audio_tts", "audio_sts": return SquircleGradient.integrations
        case "vlm":             return SquircleGradient.update
        default:                return SquircleGradient.models
        }
    }

    private func iconName(for m: ModelDTO) -> String {
        switch m.modelType {
        case "embedding": return "cube.transparent"
        case "reranker":  return "arrow.up.arrow.down"
        case "audio_stt", "audio_tts", "audio_sts": return "waveform"
        case "vlm":     return "eye"
        default:        return "cpu"
        }
    }
}

// MARK: - Helpers

func sortModelsByName(_ models: [ModelDTO]) -> [ModelDTO] {
    models.enumerated().sorted { lhs, rhs in
        // Favorites always sort first; names decide within each group.
        let lf = lhs.element.isFavorite ?? false
        let rf = rhs.element.isFavorite ?? false
        if lf != rf { return lf }
        switch lhs.element.displayTitle.localizedCaseInsensitiveCompare(
            rhs.element.displayTitle
        ) {
        case .orderedAscending:
            return true
        case .orderedDescending:
            return false
        case .orderedSame:
            return lhs.offset < rhs.offset
        }
    }.map(\.element)
}

extension ModelDTO {
    var displayTitle: String {
        displayName ?? settings?.displayName ?? id
    }
}

func formatBytes(_ bytes: Int64) -> String {
    var v = Double(bytes)
    let units = ["B", "KB", "MB", "GB", "TB"]
    var i = 0
    while v >= 1024 && i < units.count - 1 {
        v /= 1024
        i += 1
    }
    return String(format: v < 10 && i > 0 ? "%.2f %@" : "%.1f %@", v, units[i])
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/NetworkScreen.swift =====

// Phase 2 — Network.
//
// Process-wide outbound plumbing — applies to every HTTP call the server
// makes (HF, ModelScope, Sparkle,1),!s){const n=Error(`0 width match regex (${e})`)
;throw n.languageName=e,n.badRule=y.rule,n}return 1}
if(y=r,"begin"===r.type)return(e=>{
const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]]
;for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t)
;return a.skip?A+=t:(a.excludeBegin&&(A+=t),
d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r)
;if("illegal"===r.type&&!i){
const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"<unnamed>")+'"')
;throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e}
if("illegal"===r.type&&""===o)return 1
;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches")
;return A+=o,o.length}const w=v(e)
;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"')
;const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[]
;for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope)
;e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{
if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){
R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T
;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e)
;T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e,
value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){
if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t),
illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T,
context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{
language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x}
;throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{
const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)}
;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1)))
;i.unshift(t);const r=i.sort(((e,n)=>{
if(e.relevance!==n.relevance)return n.relevance-e.relevance
;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1
;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s
;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{
let n=e.className+" ";n+=e.parentNode?e.parentNode.className:""
;const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1])
;return n||(H(o.replace("{}",t[1])),
H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"}
return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return
;if(x("before:highlightElement",{el:e,language:t
}),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e)
;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),
console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),
console.warn("The element with unescaped HTML:"),
console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML)
;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a)
;e.innerHTML=r.value,e.dataset.highlighted="yes",((e,n,t)=>{const a=n&&i[n]||t
;e.classList.add("hljs"),e.classList.add("language-"+a)
})(e,t,r.language),e.result={language:r.language,re:r.relevance,
relevance:r.relevance},r.secondBest&&(e.secondBest={
language:r.secondBest.language,relevance:r.secondBest.relevance
}),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){
"loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0
}function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]}
function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{
i[e.toLowerCase()]=n}))}function k(e){const n=v(e)
;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{
e[t]&&e[t](n)}))}
"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{
N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highli
template <typename T, const int group_size, const int bits>
[[kernel]] void affine_dequantize(
    const device uint8_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    device T* out [[buffer(3)]],
    uint2 index [[thread_position_in_grid]],
    uint2 grid_dim [[threads_per_grid]]) {
  constexpr int pack_factor = get_pack_factor<bits, 8>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();

  size_t offset = index.x + grid_dim.x * size_t(index.y);
  size_t oindex = offset * pack_factor;
  size_t gindex = oindex / group_size;
  T scale = scales[gindex];
  T bias = biases[gindex];

  out += oindex;

  if (bits == 3) {
    w += offset * bytes_per_pack;
    out[0] = (w[0] & 0x7) * scale + bias;
    out[1] = ((w[0] & 0x38) >> 3) * scale + bias;
    out[2] = (((w[0] & 0xc0) >> 6) + ((w[1] & 0x1) << 2)) * scale + bias;
    out[3] = ((w[1] & 0xe) >> 1) * scale + bias;
    out[4] = ((w[1] & 0x70) >> 4) * scale + bias;
    out[5] = (((w[1] & 0x80) >> 7) + ((w[2] & 0x3) << 1)) * scale + bias;
    out[6] = ((w[2] & 0x1c) >> 2) * scale + bias;
    out[7] = ((w[2] & 0xe0) >> 5) * scale + bias;
  } else if (bits == 5) {
    w += offset * bytes_per_pack;
    out[0] = (w[0] & 0x1f) * scale + bias;
    out[1] = (((w[0] & 0xe0) >> 5) + ((w[1] & 0x3) << 3)) * scale + bias;
    out[2] = ((w[1] & 0x7c) >> 2) * scale + bias;
    out[3] = (((w[1] & 0x80) >> 7) + ((w[2] & 0xf) << 1)) * scale + bias;
    out[4] = (((w[2] & 0xf0) >> 4) + ((w[3] & 0x1) << 4)) * scale + bias;
    out[5] = ((w[3] & 0x3e) >> 1) * scale + bias;
    out[6] = (((w[3] & 0xc0) >> 6) + ((w[4] & 0x7) << 2)) * scale + bias;
    out[7] = ((w[4] & 0xf8) >> 3) * scale + bias;
  } else if (bits == 6) {
    w += offset * bytes_per_pack;
    out[0] = (w[0] & 0x3f) * scale + bias;
    out[1] = (((w[0] >> 6) & 0x03) + ((w[1] & 0x0f) << 2)) * scale + bias;
    out[2] = (((w[1] >> 4) & 0x0f) + ((w[2] & 0x03) << 4)) * scale + bias;
    out[3] = ((w[2] >> 2) & 0x3f) * scale + bias;
  } else {
    uint val = w[offset];
#pragma clang loop unroll(full)
    for (int i = 0; i < pack_factor; i++) {
      uint8_t d;
      if (bits == 1) {
        d = (val >> i) & 0x01;
      } else if (bits == 2) {
        d = (val >> (bits * i)) & 0x03;
      } else if (bits == 4) {
        d = (val >> (bits * i)) & 0x0f;
      } else if (bits == 8) {
        d = val;
      }
      out[i] = scale * d + bias;
    }
  }
}


# ===== FILE: omlx/custom_kernels/common/csrc/kernels/quantized_moe.h =====

// Copyright © 2023-2024 Apple Inc.

#include <metal_simdgroup>
#include <metal_stdlib>

constant bool align_M [[function_constant(200)]];
constant bool align_N [[function_constant(201)]];
constant bool align_K [[function_constant(202)]];

using namespace metal;

#define MLX_MTL_CONST static constant constexpr const

MLX_MTL_CONST int SIMD_SIZE = 32;
MLX_MTL_CONST int QUAD_SIZE = 4;

template <int bits, int wsize = 8>
inline constexpr short get_pack_factor() {
  return (bits == 3 || bits == 5) ? 8 : (bits == 6 ? 4 : wsize / bits);
}

template <int bits, int wsize = 8>
inline constexpr short get_bytes_per_pack() {
  constexpr int power_of_2_bits = (bits & (bits - 1)) == 0;
  return power_of_2_bits ? (wsize / 8) : (bits == 5 ? 5 : 3);
}

template <typename T, typename U, int values_per_thread, int bits>
inline U load_vector(const device T* x, thread U* x_thread) {
  static_assert(
      bits == 2 || bits == 3 || bits == 4 || bits == 5 || bits == 6 ||
          bits == 8,
      "Template undefined for bits not in {2, 3, 4, 5, 6, 8}");

  U sum = 0;

  if (bits == 2) {
    for (int i = 0; i < values_per_thread; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 4.0f;
      x_thread[i + 2] = x[i + 2] / 16.0f;
      x_thread[i + 3] = x[i + 3] / 64.0f;
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < values_per_thread; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];
      x_thread[i] = x[i];
      x_thread[i             shutil.rmtree(target_dir)
                            logger.info(f"Cleaned up cancelled download: {target_dir}")
                        except Exception as cleanup_err:
                            logger.warning(f"Failed to clean up {target_dir}: {cleanup_err}")
                    # Drop empty org folder left behind by the cancelled download.
                    parent = target_dir.parent
                    if (
                        parent != self._model_dir
                        and parent.exists()
                        and not any(parent.iterdir())
                    ):
                        try:
                            parent.rmdir()
                        except OSError as cleanup_err:
                            logger.debug(
                                f"Could not remove empty org folder {parent}: "
                                f"{cleanup_err}"
                            )
                    return

                # Success
                task.status = DownloadStatus.COMPLETED
                task.progress = 100.0
                task.downloaded_size = task.total_size or self._get_dir_size(
                    target_dir
                )
                task.completed_at = time.time()

                logger.info(
                    f"MS Download completed: {task.repo_id} -> {target_dir} "
                    f"({time.time() - task.started_at:.1f}s)"
                )

                # Trigger model pool refresh
                if self._on_complete:
                    try:
                        await self._on_complete()
                    except Exception as e:
                        logger.error(
                            f"Error in download completion callback: {e}"
                        )

        except asyncio.CancelledError:
            if task.status not in (
                DownloadStatus.CANCELLED,
                DownloadStatus.FAILED,
            ):
                task.status = DownloadStatus.CANCELLED
        except Exception as e:
            if task_id not in self._cancelled:
                task.status = DownloadStatus.FAILED
                # Provide user-friendly error messages
                err_msg = str(e)
                if "NotExistError" in type(e).__name__ or "404" in err_msg:
                    task.error = (
                        f"Model not found: {task.repo_id}. "
                        "Please check the model ID and try again."
                    )
                elif "401" in err_msg or "403" in err_msg:
                    task.error = (
                        f"Access denied for '{task.repo_id}'. "
                        "Please provide a valid ModelScope token."
                    )
                else:
                    task.error = err_msg
                logger.error(f"MS Download failed for {task.repo_id}: {e}")
        finally:
            # Stop progress polling
            progress_task = self._progress_tasks.pop(task_id, None)
            if progress_task and not progress_task.done():
                progress_task.cancel()

            # Remove from active tasks
            self._active_tasks.pop(task_id, None)

    async def _poll_progress(self, task_id: str, target_dir: Path) -> None:
        """Poll the target directory to estimate download progress.

        Uses both directory size and file modification times to detect
        activity.
        """
        task = self._tasks.get(task_id)
        if task is None:
            return

        last_size = 0
        last_activity_at = time.time()

        try:
            while task.status == DownloadStatus.DOWNLOADING:
                await asyncio.sleep(2)

                if task.status != DownloadStatus.DOWNLOADING:
                    break

                current_size = self._get_dir_size(target_dir)
                task.downloaded_size = current_size

                if task.total_size > 0:
                    # Cap at 99% until snapshot_download confirms completion
                    task.progress = min(
                        (current_size / tas future). Two sections:
//   • Outbound proxies — `http_proxy` / `https_proxy` / `no_proxy`.
//   • TLS — `ca_bundle` (custom root CA path).
//
// Mirror endpoints (HF, MS) live on the Downloads tab instead — they're
// contextual to the source the user is downloading from, so the editor
// swaps with the active source. Network stays focused on settings that
// affect every outbound call regardless of source.
//
// All fields are free-text path/URL strings, so the screen uses the
// Storage / MCP pattern: edit freely, click Apply to commit, button stays
// disabled until the draft diverges from the last-loaded values.

import SwiftUI

struct NetworkScreen: View {
    @Environment(AppServices.self) private var services
    @State private var vm = NetworkScreenVM()

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            ProxiesSection(vm: vm)
            TLSSection(vm: vm)

            HStack {
                Spacer()
                Button(String(localized: "network.button.apply",
                              defaultValue: "Apply",
                              comment: "Footer button on the Network screen that commits the edited proxy/TLS values to the server")) {
                    Task { await vm.save(client: services.client) }
                }
                .buttonStyle(.omlx(.primary))
                .disabled(!vm.hasPendingChanges || vm.isSaving)
            }
            .padding(.horizontal, 18)
            .padding(.top, 6)

            HintFooter(error: vm.lastError)
        }
        .task { await vm.load(client: services.client) }
    }
}

// MARK: - Proxies

private struct ProxiesSection: View {
    @Bindable var vm: NetworkScreenVM

    var body: some View {
        SectionHeader(
            String(localized: "network.section.proxies.title",
                   defaultValue: "Proxies",
                   comment: "Section header above the outbound proxy fields on the Network screen"),
            subtitle: String(localized: "network.section.proxies.subtitle",
                             defaultValue: "Outbound HTTP routing. Empty = no proxy. Applied via HTTP_PROXY / HTTPS_PROXY / NO_PROXY env vars.",
                             comment: "Subtitle under the Proxies section header explaining how the values are applied")
        )

        ListGroup {
            Row(label: String(localized: "network.row.http_proxy.label",
                              defaultValue: "HTTP proxy",
                              comment: "Row label for the HTTP_PROXY field on the Network screen")) {
                TextInput(
                    text: $vm.httpProxy,
                    placeholder: "http://proxy.local:8080",
                    mono: true,
                    width: 320
                )
            }
            Row(label: String(localized: "network.row.https_proxy.label",
                              defaultValue: "HTTPS proxy",
                              comment: "Row label for the HTTPS_PROXY field on the Network screen")) {
                TextInput(
                    text: $vm.httpsProxy,
                    placeholder: "http://proxy.local:8080",
                    mono: true,
                    width: 320
                )
            }
            Row(
                label: String(localized: "network.row.no_proxy.label",
                              defaultValue: "No proxy",
                              comment: "Row label for the NO_PROXY field on the Network screen"),
                sublabel: String(localized: "network.row.no_proxy.sub",
                                 defaultValue: "Comma-separated host/CIDR list to bypass the proxy.",
                                 comment: "Sublabel explaining the No proxy field format on the Network screen"),
                isLast: true
            ) {
                TextInput(
                    text: $vm.noProxy,
                    placeholder: "localhost,127.0.0.1,*.internal",
                    mono: true,
                    width: 320
                )
            }
        }
    }
}

// MARK: - TLSghtAll:w,
highlightElement:y,
highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"),
q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)},
initHighlighting:()=>{
w(),q("10.6.0","initHighlighting() deprecated.  Use highlightAll() now.")},
initHighlightingOnLoad:()=>{
w(),q("10.6.0","initHighlightingOnLoad() deprecated.  Use highlightAll() now.")
},registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){
if(K("Language definition for '{}' could not be registered.".replace("{}",e)),
!s)throw n;K(n),i=c}
i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{
languageName:e})},unregisterLanguage:e=>{delete a[e]
;for(const n of Object.keys(i))i[n]===e&&delete i[n]},
listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O,
autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{
e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{
e["before:highlightBlock"](Object.assign({block:n.el},n))
}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{
e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)},
removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{
s=!1},t.safeMode=()=>{s=!0},t.versionString="11.9.0",t.regex={concat:b,
lookahead:d,either:m,optional:u,anyNumberOfTimes:g}
;for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t
},te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{
scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{
scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},
FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/},
ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",
contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{
scope:"number",
begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",
relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/}
}),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-it + 1] = x[i + 1] / 8.0f;
      x_thread[i + 2] = x[i + 2] / 64.0f;
      x_thread[i + 3] = x[i + 3] / 2.0f;
      x_thread[i + 4] = x[i + 4] / 16.0f;
      x_thread[i + 5] = x[i + 5] / 128.0f;
      x_thread[i + 6] = x[i + 6] / 4.0f;
      x_thread[i + 7] = x[i + 7] / 32.0f;
    }
  }

  else if (bits == 4) {
    for (int i = 0; i < values_per_thread; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 16.0f;
      x_thread[i + 2] = x[i + 2] / 256.0f;
      x_thread[i + 3] = x[i + 3] / 4096.0f;
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < values_per_thread; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 32.0f;
      x_thread[i + 2] = x[i + 2] / 4.0f;
      x_thread[i + 3] = x[i + 3] / 128.0f;
      x_thread[i + 4] = x[i + 4] / 16.0f;
      x_thread[i + 5] = x[i + 5] / 2.0f;
      x_thread[i + 6] = x[i + 6] / 64.0f;
      x_thread[i + 7] = x[i + 7] / 8.0f;
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < values_per_thread; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 64.0f;
      x_thread[i + 2] = x[i + 2] / 16.0f;
      x_thread[i + 3] = x[i + 3] / 4.0f;
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < values_per_thread; i++) {
      sum += x[i];
      x_thread[i] = x[i];
    }
  }

  return sum;
}

template <typename T, typename U, int values_per_thread, int bits>
inline U load_vector_safe(const device T* x, thread U* x_thread, int N) {
  static_assert(
      bits == 2 || bits == 3 || bits == 4 || bits == 5 || bits == 6 ||
          bits == 8,
      "Template undefined for bits not in {2, 3, 4, 5, 6, 8}");

  U sum = 0;

  if (bits == 2) {
    for (int i = 0; i < N; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 4.0f;
      x_thread[i + 2] = x[i + 2] / 16.0f;
      x_thread[i + 3] = x[i + 3] / 64.0f;
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < N; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];

      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 8.0f;
      x_thread[i + 2] = x[i + 2] / 64.0f;
      x_thread[i + 3] = x[i + 3] / 2.0f;
      x_thread[i + 4] = x[i + 4] / 16.0f;
      x_thread[i + 5] = x[i + 5] / 128.0f;
      x_thread[i + 6] = x[i + 6] / 4.0f;
      x_thread[i + 7] = x[i + 7] / 32.0f;
    }
  }

  else if (bits == 4) {
    for (int i = 0; i < N; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 16.0f;
      x_thread[i + 2] = x[i + 2] / 256.0f;
      x_thread[i + 3] = x[i + 3] / 4096.0f;
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < N; i += 8) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3] + x[i + 4] + x[i + 5] +
          x[i + 6] + x[i + 7];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 32.0f;
      x_thread[i + 2] = x[i + 2] / 4.0f;
      x_thread[i + 3] = x[i + 3] / 128.0f;
      x_thread[i + 4] = x[i + 4] / 16.0f;
      x_thread[i + 5] = x[i + 5] / 2.0f;
      x_thread[i + 6] = x[i + 6] / 64.0f;
      x_thread[i + 7] = x[i + 7] / 8.0f;
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < N; i += 4) {
      sum += x[i] + x[i + 1] + x[i + 2] + x[i + 3];
      x_thread[i] = x[i];
      x_thread[i + 1] = x[i + 1] / 64.0f;
      x_thread[i + 2] = x[i + 2] / 16.0f;
      x_thread[i + 3] = x[i + 3] / 4.0f;
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < N; i++) {
      sum += x[i];
      x_thread[i] = x[i];
    }
  }

  for (int i = N; i < values_per_thread; i++) {
    x_thread[i] = 0;
  }

  return sum;
}

template <typename U, int values_per_thread, int bits>
inline U qdot(
    const device uint8_t* w,
    const thread U* x_thread,
    U scale,
    U bias,
    U sum) {
  static_assert(
      bits == 2 || bits == 3 k.total_size) * 100, 99.0
                    )

                # Activity detection: size change OR file mtime change
                if current_size != last_size:
                    last_size = current_size
                    last_activity_at = time.time()
                else:
                    latest_mtime = self._get_latest_mtime(target_dir)
                    if latest_mtime > last_activity_at:
                        last_activity_at = latest_mtime

                # Stall detection
                if (
                    current_size > 0
                    and (time.time() - last_activity_at) > _STALL_TIMEOUT
                ):
                    task.status = DownloadStatus.FAILED
                    task.error = (
                        f"Download stalled: no progress for {_STALL_TIMEOUT}s. "
                        "Try retrying the download."
                    )
                    logger.warning(
                        f"MS Download stalled for {task.repo_id} "
                        f"(task_id={task_id})"
                    )
                    # Cancel the snapshot_download thread
                    active_task = self._active_tasks.get(task_id)
                    if active_task and not active_task.done():
                        active_task.cancel()
                    break
        except asyncio.CancelledError:
            pass

    @staticmethod
    def _get_latest_mtime(path: Path) -> float:
        """Return the most recent modification time of any file in a directory."""
        if not path.exists():
            return 0.0
        latest = 0.0
        try:
            for f in path.rglob("*"):
                if f.is_file():
                    try:
                        mt = f.stat().st_mtime
                        if mt > latest:
                            latest = mt
                    except OSError:
                        pass
        except OSError:
            pass
        return latest

    @staticmethod
    def _get_dir_size(path: Path) -> int:
        """Calculate total size of all files in a directory."""
        if not path.exists():
            return 0
        total = 0
        try:
            for f in path.rglob("*"):
                if f.is_file():
                    try:
                        total += f.stat().st_size
                    except OSError:
                        pass
        except OSError:
            pass
        return total


# ===== FILE: omlx/admin/oq_manager.py =====

# SPDX-License-Identifier: Apache-2.0
"""oQ Quantization task manager for the admin panel.

Manages quantization tasks with progress tracking, following the same pattern
as hf_downloader.py (DownloadTask / HFDownloader).
"""

import asyncio
import enum
import hashlib
import json
import logging
import time
import uuid
from dataclasses import dataclass, field
from pathlib import Path
from typing import Callable, Optional

try:
    import mlx.core as mx

    HAS_MLX = True
except ImportError:
    HAS_MLX = False

from ..model_discovery import _has_vision_subconfig

logger = logging.getLogger(__name__)


class _QuantCancelled(Exception):
    """Raised by progress callback when task is cancelled."""

    pass


class QuantStatus(str, enum.Enum):
    """Status of a quantization task."""

    PENDING = "pending"
    LOADING = "loading"
    QUANTIZING = "quantizing"
    SAVING = "saving"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


_ACTIVE_STATUSES = {
    QuantStatus.PENDING,
    QuantStatus.LOADING,
    QuantStatus.QUANTIZING,
    QuantStatus.SAVING,
}


@dataclass
class QuantTask:
    """Represents a single oQ quantization task."""

    task_id: str
    model_name: str
    model_path: str
    oq_level: float
    output_name: str
    output_path: str
    status: QuantStatus = QuantStatus.PENDING
    progress: float = 0.0
    phase: str = ""
    progress_detail: str = ""
    progress_meta: dict = field(default_factory=dict)
    error: str = ""
    created_at: float = field(default_factory=time.time)
    started_at: float = 0.0
    completed_at

private struct TLSSection: View {
    @Bindable var vm: NetworkScreenVM

    var body: some View {
        SectionHeader(
            String(localized: "network.section.tls.title",
                   defaultValue: "TLS",
                   comment: "Section header above the TLS / custom CA fields on the Network screen"),
            subtitle: String(localized: "network.section.tls.subtitle",
                             defaultValue: "Custom root CA for environments with TLS-inspecting proxies.",
                             comment: "Subtitle under the TLS section header on the Network screen")
        )

        ListGroup {
            Row(
                label: String(localized: "network.row.ca_bundle.label",
                              defaultValue: "CA bundle",
                              comment: "Row label for the custom CA bundle path field on the Network screen"),
                sublabel: String(localized: "network.row.ca_bundle.sub",
                                 defaultValue: "Absolute path to a PEM-encoded CA bundle. Empty = system trust store.",
                                 comment: "Sublabel explaining the CA bundle field on the Network screen"),
                isLast: true
            ) {
                TextInput(
                    text: $vm.caBundle,
                    placeholder: "/etc/ssl/certs/ca-bundle.pem",
                    mono: true,
                    width: 320
                )
            }
        }
    }
}

// MARK: - Hint footer

private struct HintFooter: View {
    let error: String?

    var body: some View {
        if let error {
            Text(error)
                .font(.omlxText(11))
                .foregroundStyle(.red)
                .padding(.horizontal, 18)
                .padding(.top, 8)
        }
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/PerformanceScreen.swift =====

// Phase 3 — Performance.
//
// One tab for every "how the engine runs" knob. Three sections:
//   • Scheduler — max_concurrent_requests (moved from ServerScreen for
//     scheduler coherence), embedding_batch_size, and chunked_prefill.
//   • Memory & Lifecycle — prefill memory guard tier, server-wide idle
//     timeout, model fallback routing.
//   • Cache — master enable toggle gates a hot-cache toggle + size, a
//     cold-cache directory + size, and an advanced initial-blocks tuning
//     knob (requires restart).
//
// All fields are server-side already (`omlx/admin/routes.py:198-235`)
// — Phase 3 is pure UI. Single Apply button at the bottom, Storage /
// Network pattern: disabled until at least one trimmed draft diverges
// from its loaded value, and only changed fields are sent in the PATCH
// so out-of-band edits to siblings stay intact.

import SwiftUI

struct PerformanceScreen: View {
    @Environment(AppServices.self) private var services
    @State private var vm = PerformanceScreenVM()

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            SchedulerSection(vm: vm)
            MemoryLifecycleSection(vm: vm)
            CacheSection(vm: vm)

            HStack {
                Spacer()
                Button(String(localized: "performance.button.apply",
                              defaultValue: "Apply",
                              comment: "Apply button at the bottom of the Performance screen")) {
                    Task { await vm.save(client: services.client) }
                }
                .buttonStyle(.omlx(.primary))
                .disabled(!vm.hasPendingChanges || vm.isSaving)
            }
            .padding(.horizontal, 18)
            .padding(.top, 6)

            if let error = vm.lastError {
                Text(error)
                    .font(.omlxText(11))
                    .foregroundStyle(.red)
                    .padding(.horizontal, 18)
                    .padding(.top, 8)
            }
        }
        .task { await vm.load(client: services.client) }
    }
}

// MARK: - Scheduler

private struct SchedulerSection: View {
    @Bindable var vm: PerformanceScreenVM

    var body:eration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top"|| bits == 4 || bits == 5 || bits == 6 ||
          bits == 8,
      "Template undefined for bits not in {2, 3, 4, 5, 6, 8}");

  U accum = 0;

  if (bits == 2) {
    for (int i = 0; i < (values_per_thread / 4); i++) {
      accum +=
          (x_thread[4 * i] * (w[i] & 0x03) +
           x_thread[4 * i + 1] * (w[i] & 0x0c) +
           x_thread[4 * i + 2] * (w[i] & 0x30) +
           x_thread[4 * i + 3] * (w[i] & 0xc0));
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      x_thread += 8 * i;
      w += 3 * i;

      accum += (w[0] & 0x07) * x_thread[0];
      accum += (w[0] & 0x38) * x_thread[1];
      accum += (w[0] & 0xc0) * x_thread[2];
      accum += (w[1] & 0x01) * (x_thread[2] * 256.0f);

      accum += (w[1] & 0x0e) * x_thread[3];
      accum += (w[1] & 0x70) * x_thread[4];
      accum += (w[1] & 0x80) * x_thread[5];
      accum += (w[2] & 0x03) * (x_thread[5] * 256.0f);

      accum += (w[2] & 0x1c) * x_thread[6];
      accum += (w[2] & 0xe0) * x_thread[7];
    }
  }

  else if (bits == 4) {
    const device uint16_t* ws = (const device uint16_t*)w;
    for (int i = 0; i < (values_per_thread / 4); i++) {
      accum +=
          (x_thread[4 * i] * (ws[i] & 0x000f) +
           x_thread[4 * i + 1] * (ws[i] & 0x00f0) +
           x_thread[4 * i + 2] * (ws[i] & 0x0f00) +
           x_thread[4 * i + 3] * (ws[i] & 0xf000));
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      x_thread += 8 * i;
      w += 5 * i;

      accum += (w[0] & 0x1f) * x_thread[0];
      accum += (w[0] & 0xe0) * x_thread[1];
      accum += (w[1] & 0x3) * (x_thread[1] * 256.0f);
      accum += (w[1] & 0x7c) * x_thread[2];
      accum += (w[1] & 0x80) * x_thread[3];
      accum += (w[2] & 0xf) * (x_thread[3] * 256.0f);
      accum += (w[2] & 0xf0) * x_thread[4];
      accum += (w[3] & 0x1) * (x_thread[4] * 256.0f);
      accum += (w[3] & 0x3e) * x_thread[5];
      accum += (w[3] & 0xc0) * x_thread[6];
      accum += (w[4] & 0x7) * (x_thread[6] * 256.0f);
      accum += (w[4] & 0xf8) * x_thread[7];
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < (values_per_thread / 4); i++) {
      x_thread += 4 * i;
      w += 3 * i;

      accum += (w[0] & 0x3f) * x_thread[0];

      accum += (w[0] & 0xc0) * x_thread[1];
      accum += (w[1] & 0x0f) * (x_thread[1] * 256.0f);

      accum += (w[1] & 0xf0) * x_thread[2];
      accum += (w[2] & 0x03) * (x_thread[2] * 256.0f);

      accum += (w[2] & 0xfc) * x_thread[3];
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < values_per_thread; i++) {
      accum += x_thread[i] * w[i];
    }
  }

  return scale * accum + sum * bias;
}

template <typename U, int values_per_thread, int bits>
inline U qdot_safe(
    const device uint8_t* w,
    const thread U* x_thread,
    U scale,
    U bias,
    U sum,
    int N) {
  static_assert(
      bits == 2 || bits == 3 || bits == 4 || bits == 5 || bits == 6 ||
          bits == 8,
      "Template undefined for bits not in {2, 3, 4, 5, 6, 8}");

  U accum = 0;

  if (bits == 2) {
    for (int i = 0; i < (N / 4); i++) {
      accum +=
          (x_thread[4 * i] * (w[i] & 0x03) +
           x_thread[4 * i + 1] * (w[i] & 0x0c) +
           x_thread[4 * i + 2] * (w[i] & 0x30) +
           x_thread[4 * i + 3] * (w[i] & 0xc0));
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < (N / 8); i++) {
      x_thread += 8 * i;
      w += 3 * i;

      accum += (w[0] & 0x07) * x_thread[0];
      accum += (w[0] & 0x38) * x_thread[1];
      accum += (w[0] & 0xc0) * x_thread[2];
      accum += (w[1] & 0x01) * (x_thread[2] * 256.0f);

      accum += (w[1] & 0x0e) * x_thread[3];
      accum += (w[1] & 0x70) * x_thread[4];
      accum += (w[1] & 0x80) * x_thread[5];
      accum += (w[2] & 0x03) * (x_thread[5] * 256.0f);

      accum += (w[2] & 0x1c) * x_thread[6];
      accum += (w[2] & 0xe0) * x_thread[7];
    }
  }

  else if (bits == 4) {
    const device uint16_t* ws = (const device uint16_t*)w;
    for (int i = 0; i < (N / 4); i++) {
      accum +=
          (x_thread[4 * i] * (ws[: float = 0.0
    source_size: int = 0
    output_size: int = 0
    group_size: int = 64
    sensitivity_model_path: str = ""
    text_only: bool = False
    dtype: str = "bfloat16"
    preserve_mtp: bool = False
    auto_proxy_sensitivity: bool = True
    enhanced: bool = False
    imatrix_cache_path: str = ""
    imatrix_reuse_cache: bool = True
    imatrix_strict: bool = False
    imatrix_num_samples: int = 128
    imatrix_seq_length: int = 512
    mtp_assistant_model_path: str = ""

    def to_dict(self) -> dict:
        """Serialize task to JSON-compatible dict."""
        return {
            "task_id": self.task_id,
            "model_name": self.model_name,
            "model_path": self.model_path,
            "oq_level": self.oq_level,
            "output_name": self.output_name,
            "output_path": self.output_path,
            "status": self.status.value,
            "progress": round(self.progress, 1),
            "phase": self.phase,
            "progress_detail": self.progress_detail,
            "progress_meta": self.progress_meta,
            "error": self.error,
            "created_at": self.created_at,
            "started_at": self.started_at,
            "completed_at": self.completed_at,
            "source_size": self.source_size,
            "output_size": self.output_size,
            "dtype": self.dtype,
            "enhanced": self.enhanced,
            "imatrix_cache_path": self.imatrix_cache_path,
        }


def _dir_size(path: Path) -> int:
    """Get total size of files in a directory."""
    if not path.exists():
        return 0
    return sum(f.stat().st_size for f in path.rglob("*") if f.is_file())


def _format_size(size_bytes: int) -> str:
    """Format byte count as human-readable string."""
    if size_bytes < 1024:
        return f"{size_bytes} B"
    elif size_bytes < 1024**2:
        return f"{size_bytes / 1024:.1f} KB"
    elif size_bytes < 1024**3:
        return f"{size_bytes / 1024**2:.1f} MB"
    else:
        return f"{size_bytes / 1024**3:.1f} GB"


class OQManager:
    """Manages oQ quantization tasks with async execution and progress tracking.

    Follows the same pattern as HFDownloader: semaphore-guarded sequential
    execution, polling-based progress, cooperative cancellation.
    """

    def __init__(
        self,
        model_dirs: list[str],
        on_complete: Optional[Callable] = None,
    ):
        self._model_dirs = [Path(d) for d in model_dirs]
        self._output_dir = self._model_dirs[0] if self._model_dirs else Path(".")
        self._tasks: dict[str, QuantTask] = {}
        self._active_tasks: dict[str, asyncio.Task] = {}
        self._progress_tasks: dict[str, asyncio.Task] = {}
        self._on_complete = on_complete
        self._cancelled: set[str] = set()
        self._quant_sem = asyncio.Semaphore(1)

    def update_model_dirs(self, model_dirs: list[str]) -> None:
        """Update model directory paths."""
        self._model_dirs = [Path(d) for d in model_dirs]
        if self._model_dirs:
            self._output_dir = self._model_dirs[0]

    async def list_quantizable_models(self) -> tuple[list[dict], list[dict]]:
        """Scan all model dirs. Returns (source_models, all_models)."""

        def _scan() -> tuple[list[dict], list[dict]]:
            from ..oq import estimate_memory, validate_quantizable
            from ..utils.model_loading import (
                _checkpoint_has_mtp_weights,
                _has_mtp_heads,
            )

            source_models = []
            all_models = []
            seen: set[str] = set()

            for model_dir in self._model_dirs:
                if not model_dir.exists():
                    continue
                for subdir in sorted(model_dir.iterdir()):
                    if not subdir.is_dir():
                        continue
                    candidates = []
                    if (subdir / "config.json").exists():
                        candidates.append(subdir)
                    else:
                        for child in sorted(subdir.iterdir()):
                some View {
        SectionHeader(
            String(localized: "performance.section.scheduler",
                   defaultValue: "Scheduler",
                   comment: "Section header for the scheduler rows"),
            subtitle: String(localized: "performance.section.scheduler.sub",
                             defaultValue: "How many requests run at once and how the engine batches them.",
                             comment: "Subtitle for the Scheduler section")
        )

        ListGroup {
            Row(
                label: String(localized: "performance.scheduler.max_concurrent",
                              defaultValue: "Max Concurrent Requests",
                              comment: "Row label for max concurrent requests"),
                sublabel: String(localized: "performance.scheduler.max_concurrent.sub",
                                 defaultValue: "Cap on simultaneous /v1 requests.",
                                 comment: "Sublabel for max concurrent requests")
            ) {
                TextInput(text: $vm.maxConcurrentText, mono: true, width: 90)
            }
            Row(
                label: String(localized: "performance.scheduler.embedding_batch_size",
                              defaultValue: "Embedding Batch Size",
                              comment: "Row label for embedding batch size"),
                sublabel: String(localized: "performance.scheduler.embedding_batch_size.sub",
                                 defaultValue: "Max input texts per embedding forward pass.",
                                 comment: "Sublabel for embedding batch size")
            ) {
                TextInput(text: $vm.embeddingBatchSizeText, mono: true, width: 90)
            }
            Row(
                label: String(localized: "performance.scheduler.chunked_prefill",
                              defaultValue: "Chunked Prefill",
                              comment: "Row label for chunked prefill toggle"),
                sublabel: String(localized: "performance.scheduler.chunked_prefill.sub",
                                 defaultValue: "Split long prompts across scheduler ticks so other requests can interleave.",
                                 comment: "Sublabel for chunked prefill toggle")
            ) {
                Toggle("", isOn: $vm.chunkedPrefill)
                    .labelsHidden().toggleStyle(.switch)
            }
            Row(
                label: String(localized: "performance.scheduler.prefill_priority",
                              defaultValue: "Prefill Priority",
                              comment: "Row label for the prefill priority segmented control"),
                sublabel: String(localized: "performance.scheduler.prefill_priority.sub",
                                 defaultValue: "Max Context trades prefill speed for larger prompts under memory pressure; Speed keeps full prefill speed and rejects prompts that would not fit.",
                                 comment: "Sublabel for the prefill priority segmented control"),
                isLast: true
            ) {
                Segmented(
                    selection: $vm.prefillPriority,
                    options: [
                        (value: "context",
                         label: String(localized: "prefill_priority.option.max_context",
                                       defaultValue: "Max Context",
                                       comment: "Prefill priority option that favors the largest context")),
                        (value: "speed",
                         label: String(localized: "prefill_priority.option.speed",
                                       defaultValue: "Speed",
                                       comment: "Prefill priority option that favors prefill speed")),
                    ],
                    icons: ["arrow.up.left.and.arrow.down.right", "speedometer"]
                )
                .frame(width: 240)
            }
        }
    }
}

// MARK: - Memory & Lifecycle

private struct MemoryLifecycleSection: View {
    ,"page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le)
;var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={
className:"number",variants:[{
begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{
begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{
begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{
begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{
begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{
begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],
relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))}
const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye)
;function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/,
end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{
const t=e[0].length+e.index,a=e.input[t]
;if("<"===a||","===a)return void n.ignoreMatch();let i
;">"===a&&(((e,{after:n})=>{const t="</"+e[0].slice(1)
;return-1!==e.input.indexOf(t,n)})(e,{after:t})||n.ignoreMatci] & 0x000f) +
           x_thread[4 * i + 1] * (ws[i] & 0x00f0) +
           x_thread[4 * i + 2] * (ws[i] & 0x0f00) +
           x_thread[4 * i + 3] * (ws[i] & 0xf000));
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < (N / 8); i++) {
      x_thread += 8 * i;
      w += 5 * i;

      accum += (w[0] & 0x1f) * x_thread[0];
      accum += (w[0] & 0xe0) * x_thread[1];
      accum += (w[1] & 0x3) * (x_thread[1] * 256.0f);
      accum += (w[1] & 0x7c) * x_thread[2];
      accum += (w[1] & 0x80) * x_thread[3];
      accum += (w[2] & 0xf) * (x_thread[3] * 256.0f);
      accum += (w[2] & 0xf0) * x_thread[4];
      accum += (w[3] & 0x1) * (x_thread[4] * 256.0f);
      accum += (w[3] & 0x3e) * x_thread[5];
      accum += (w[3] & 0xc0) * x_thread[6];
      accum += (w[4] & 0x7) * (x_thread[6] * 256.0f);
      accum += (w[4] & 0xf8) * x_thread[7];
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < (N / 4); i++) {
      x_thread += 4 * i;
      w += 3 * i;

      accum += (w[0] & 0x3f) * x_thread[0];

      accum += (w[0] & 0xc0) * x_thread[1];
      accum += (w[1] & 0x0f) * (x_thread[1] * 256.0f);

      accum += (w[1] & 0xf0) * x_thread[2];
      accum += (w[2] & 0x03) * (x_thread[2] * 256.0f);

      accum += (w[2] & 0xfc) * x_thread[3];
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < N; i++) {
      accum += x_thread[i] * w[i];
    }
  }

  return scale * accum + sum * bias;
}

template <typename U, int values_per_thread, int bits>
inline void
qouter(const thread uint8_t* w, U x, U scale, U bias, thread U* result) {
  static_assert(
      bits == 2 || bits == 3 || bits == 4 || bits == 5 || bits == 6 ||
          bits == 8,
      "Template undefined for bits not in {2, 3, 4, 5, 6, 8}");

  if (bits == 2) {
    U s[4] = {scale, scale / 4.0f, scale / 16.0f, scale / 64.0f};
    for (int i = 0; i < (values_per_thread / 4); i++) {
      result[4 * i] += x * (s[0] * (w[i] & 0x03) + bias);
      result[4 * i + 1] += x * (s[1] * (w[i] & 0x0c) + bias);
      result[4 * i + 2] += x * (s[2] * (w[i] & 0x30) + bias);
      result[4 * i + 3] += x * (s[3] * (w[i] & 0xc0) + bias);
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      uint8_t w0 = w[3 * i];
      uint8_t w1 = w[3 * i + 1];
      uint8_t w2 = w[3 * i + 2];

      result[8 * i] += x * ((w0 & 0x7) * scale + bias);
      result[8 * i + 1] += x * (((w0 & 0x38) >> 3) * scale + bias);
      result[8 * i + 2] +=
          x * ((((w0 & 0xc0) >> 6) + ((w1 & 0x1) << 2)) * scale + bias);
      result[8 * i + 3] += x * (((w1 & 0xe) >> 1) * scale + bias);
      result[8 * i + 4] += x * (((w1 & 0x70) >> 4) * scale + bias);
      result[8 * i + 5] +=
          x * ((((w1 & 0x80) >> 7) + ((w2 & 0x3) << 1)) * scale + bias);
      result[8 * i + 6] += x * (((w2 & 0x1c) >> 2) * scale + bias);
      result[8 * i + 7] += x * (((w2 & 0xe0) >> 5) * scale + bias);
    }
  }

  else if (bits == 4) {
    U s[2] = {scale, scale / 16.0f};
    for (int i = 0; i < (values_per_thread / 2); i++) {
      result[2 * i] += x * (s[0] * (w[i] & 0x0f) + bias);
      result[2 * i + 1] += x * (s[1] * (w[i] & 0xf0) + bias);
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < (values_per_thread / 8); i++) {
      uint8_t w0 = w[5 * i];
      uint8_t w1 = w[5 * i + 1];
      uint8_t w2 = w[5 * i + 2];
      uint8_t w3 = w[5 * i + 3];
      uint8_t w4 = w[5 * i + 4];
      result[8 * i] += x * ((w0 & 0x1f) * scale + bias);
      result[8 * i + 1] +=
          x * ((((w0 & 0xe0) >> 5) + ((w1 & 0x3) << 3)) * scale + bias);
      result[8 * i + 2] += x * (((w1 & 0x7c) >> 2) * scale + bias);
      result[8 * i + 3] +=
          x * ((((w1 & 0x80) >> 7) + ((w2 & 0xf) << 1)) * scale + bias);
      result[8 * i + 4] +=
          x * ((((w2 & 0xf0) >> 4) + ((w3 & 0x1) << 4)) * scale + bias);
      result[8 * i + 5] += x * (((w3 & 0x3e) >> 1) * scale + bias);
      result[8 * i + 6] +=
          x * ((((w3 & 0xc0) >> 6) + ((w4 & 0x7) << 2)) * scale + bias);
      result[8 * i + 7] += x * (((w4 & 0xf8) >> 3) * scale + bias);
    }
  }

  else if (bits == 6)             if child.is_dir() and (child / "config.json").exists():
                                candidates.append(child)

                    for path in candidates:
                        if path.name in seen:
                            continue
                        seen.add(path.name)
                        try:
                            with open(path / "config.json") as f:
                                config = json.load(f)
                            size = sum(
                                f.stat().st_size for f in path.glob("*.safetensors")
                            )
                            if size == 0:
                                size = sum(f.stat().st_size for f in path.glob("*.bin"))
                            if size == 0:
                                continue
                            tc = config.get("text_config", {})
                            has_mtp = _has_mtp_heads(
                                config
                            ) and _checkpoint_has_mtp_weights(path)
                            info = {
                                "name": path.name,
                                "path": str(path),
                                "size": size,
                                "size_formatted": _format_size(size),
                                "model_type": config.get("model_type", "")
                                or tc.get("model_type", ""),
                                "is_quantized": "quantization" in config,
                                # Treat vision_config / vit_config / mm_vision_tower as VLM
                                # evidence (Molmo / Molmo2 use vit_config; FastVLM uses
                                # mm_vision_tower). Same predicate as model_discovery.
                                "is_vlm": _has_vision_subconfig(config),
                                "has_mtp_heads": has_mtp,
                                "hidden_size": tc.get("hidden_size")
                                or config.get("hidden_size")
                                or 0,
                            }
                            all_models.append(info)
                            if validate_quantizable(config):
                                info_full = dict(info)
                                info_full["num_layers"] = config.get(
                                    "num_hidden_layers", 0
                                ) or tc.get("num_hidden_layers", 0)
                                info_full["num_experts"] = config.get(
                                    "num_local_experts", 0
                                )
                                info_full["memory_streaming"] = estimate_memory(size)
                                source_models.append(info_full)
                        except Exception:
                            continue
            return source_models, all_models

        return await asyncio.to_thread(_scan)

    async def start_quantization(
        self,
        model_path: str,
        oq_level: float,
        group_size: int = 64,
        sensitivity_model_path: str = "",
        text_only: bool = False,
        dtype: str = "bfloat16",
        preserve_mtp: bool = False,
        auto_proxy_sensitivity: bool = True,
        enhanced: bool = False,
        imatrix_cache_path: str = "",
        imatrix_reuse_cache: bool = True,
        imatrix_strict: bool = False,
        imatrix_num_samples: int = 128,
        imatrix_seq_length: int = 512,
        mtp_assistant_model_path: str = "",
    ) -> QuantTask:
        """Start a quantization job.

        Args:
            model_path: Path to source model directory.
            oq_level: oQ level from OQ_LEVELS.
            dtype: Target fp dtype for non-quantized weights and quant
                scales/biases. "bfloat16" (default) or "float16".
            mtp_assistant_model_path: Optional checkpoint whose MTP head is
                merged into the output. A gemma4_assistant donor uses the
                assistant merge; any other donor grafts its native
                Qwen3.5/3@Bindable var vm: PerformanceScreenVM
    @Environment(\.omlxTheme) private var theme

    var body: some View {
        SectionHeader(
            String(localized: "performance.section.memory",
                   defaultValue: "Memory & Lifecycle",
                   comment: "Section header for memory and lifecycle settings"),
            subtitle: String(localized: "performance.section.memory.sub",
                             defaultValue: "Memory admission control and auto-unload behavior.",
                             comment: "Subtitle explaining memory and lifecycle settings")
        )

        ListGroup {
            Row(
                label: String(localized: "performance.memory.prefill_guard",
                              defaultValue: "Prefill Memory Guard",
                              comment: "Row label for prefill memory guard toggle"),
                sublabel: String(localized: "performance.memory.prefill_guard.sub",
                                 defaultValue: "Preflight prefill memory before kicking the engine and defer generation scheduling near the ceiling.",
                                 comment: "Sublabel for prefill memory guard")
            ) {
                Toggle("", isOn: $vm.prefillMemoryGuard)
                    .labelsHidden().toggleStyle(.switch)
            }
            Row(
                label: String(localized: "performance.memory.guard_tier",
                              defaultValue: "Memory Guard Tier",
                              comment: "Row label for memory guard tier popup"),
                sublabel: vm.memoryGuardTierDescription
            ) {
                Popup(
                    selection: $vm.memoryGuardTier,
                    width: 150,
                    options: [
                        ("safe",
                         String(localized: "performance.memory.guard_tier.safe",
                                defaultValue: "Safe",
                                comment: "Memory guard tier option: safe")),
                        ("balanced",
                         String(localized: "performance.memory.guard_tier.balanced",
                                defaultValue: "Balanced",
                                comment: "Memory guard tier option: balanced")),
                        ("aggressive",
                         String(localized: "performance.memory.guard_tier.aggressive",
                                defaultValue: "Aggressive",
                                comment: "Memory guard tier option: aggressive")),
                        ("custom",
                         String(localized: "performance.memory.guard_tier.custom",
                                defaultValue: "Custom",
                                comment: "Memory guard tier option: custom")),
                    ]
                )
                .disabled(!vm.prefillMemoryGuard)
            }
            if vm.prefillMemoryGuard && vm.memoryGuardTier == "custom" {
                Row(
                    label: String(localized: "performance.memory.custom_ceiling",
                                  defaultValue: "Custom Ceiling",
                                  comment: "Row label for memory guard custom ceiling"),
                    sublabel: String(localized: "performance.memory.custom_ceiling.sub",
                                     defaultValue: "Fixed process memory ceiling in GB. Used only with the Custom tier.",
                                     comment: "Sublabel for memory guard custom ceiling")
                ) {
                    TextInput(
                        text: $vm.memoryGuardCustomCeilingText,
                        placeholder: String(localized: "performance.memory.custom_ceiling.placeholder",
                                            defaultValue: "GB",
                                            comment: "Placeholder for custom memory guard ceiling"),
                        mono: true,
                        suffix: "GB",
                        width: 110
                    )
                }
            }
        h())
;const r=e.input.substring(t)
;((i=r.match(/^\s*=/))||(i=r.match(/^\s+extends\s+/))&&0===i.index)&&n.ignoreMatch()
}},i={$pattern:_e,keyword:he,literal:fe,built_in:ve,"variable.language":we
},r="[0-9](_?[0-9])*",s=`\\.(${r})`,o="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",l={
className:"number",variants:[{
begin:`(\\b(${o})((${s})|\\.)?|(${s}))[eE][+-]?(${r})\\b`},{
begin:`\\b(${o})\\b((${s})\\b|\\.)?|(${s})\\b`},{
begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{
begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{
begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{
begin:"\\b0[0-7]+n?\\b"}],relevance:0},c={className:"subst",begin:"\\$\\{",
end:"\\}",keywords:i,contains:[]},d={begin:"html`",end:"",starts:{end:"`",
returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"xml"}},g={
begin:"css`",end:"",starts:{end:"`",returnEnd:!1,
contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"css"}},u={begin:"gql`",end:"",
starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c],
subLanguage:"graphql"}},b={className:"string",begin:"`",end:"`",
contains:[e.BACKSLASH_ESCAPE,c]},m={className:"comment",
variants:[e.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{
begin:"(?=@[A-Za-z]+)",relevance:0,contains:[{className:"doctag",
begin:"@[A-Za-z]+"},{className:"type",begin:"\\{",end:"\\}",excludeEnd:!0,
excludeBegin:!0,relevance:0},{className:"variable",begin:t+"(?=\\s*(-)|$)",
endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]
}),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]
},p=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,{match:/\$\d+/},l]
;c.contains=p.concat({begin:/\{/,end:/\}/,keywords:i,contains:["self"].concat(p)
});const _=[].concat(m,c.contains),h=_.concat([{begin:/\(/,end:/\)/,keywords:i,
contains:["self"].concat(_)}]),f={className:"params",begin:/\(/,end:/\)/,
excludeBegin:!0,excludeEnd:!0,keywords:i,contains:h},E={variants:[{
match:[/class/,/\s+/,t,/\s+/,/extends/,/\s+/,n.concat(t,"(",n.concat(/\./,t),")*")],
scope:{1:"keyword",3:"title.class",5:"keyword",7:"title.class.inherited"}},{
match:[/class/,/\s+/,t],scope:{1:"keyword",3:"title.class"}}]},y={relevance:0,
match:n.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),
className:"title.class",keywords:{_:[...Ee,...ye]}},N={variants:[{
match:[/function/,/\s+/,t,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}],
className:{1:"keyword",3:"title.function"},label:"func.def",contains:[f],
illegal:/%/},w={
match:n.concat(/\b/,(v=[...Ne,"super","import"],n.concat("(?!",v.join("|"),")")),t,n.lookahead(/\(/)),
className:"title.function",relevance:0};var v;const O={
begin:n.concat(/\./,n.lookahead(n.concat(t,/(?![0-9A-Za-z$_(])/))),end:t,
excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},k={
match:[/get|set/,/\s+/,t,/(?=\()/],className:{1:"keyword",3:"title.function"},
contains:[{begin:/\(\)/},f]
},x="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+e.UNDERSCORE_IDENT_RE+")\\s*=>",M={
match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)],
keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]}
;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{
PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/,
contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{
label:"use_strict",className:"meta",relevance:10,
begin:/^\s*['"]use (strict|asm)['"]/
},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{
className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{
begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",
keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{
className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{
className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{
className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,
excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/,
relevance:0},{variants:[{begin:"<>",end:"</>"},{
match:/<[A- {
    for (int i = 0; i < (values_per_thread / 4); i++) {
      uint8_t w0 = w[3 * i];
      uint8_t w1 = w[3 * i + 1];
      uint8_t w2 = w[3 * i + 2];

      result[4 * i] += x * ((w0 & 0x3f) * scale + bias);
      result[4 * i + 1] +=
          x * ((((w0 >> 6) & 0x03) + ((w1 & 0x0f) << 2)) * scale + bias);
      result[4 * i + 2] +=
          x * ((((w1 >> 4) & 0x0f) + ((w2 & 0x03) << 4)) * scale + bias);
      result[4 * i + 3] += x * (((w2 >> 2) & 0x3f) * scale + bias);
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < values_per_thread; i++) {
      result[i] += x * (scale * w[i] + bias);
    }
  }
}

template <typename U, int N, int bits>
inline void
dequantize(const device uint8_t* w, U scale, U bias, threadgroup U* w_local) {
  static_assert(
      bits == 2 || bits == 3 || bits == 4 || bits == 5 || bits == 6 ||
          bits == 8,
      "Template undefined for bits not in {2, 3, 4, 5, 6, 8}");

  if (bits == 2) {
    U s[4] = {
        scale,
        scale / static_cast<U>(4.0f),
        scale / static_cast<U>(16.0f),
        scale / static_cast<U>(64.0f)};
    for (int i = 0; i < (N / 4); i++) {
      w_local[4 * i] = s[0] * (w[i] & 0x03) + bias;
      w_local[4 * i + 1] = s[1] * (w[i] & 0x0c) + bias;
      w_local[4 * i + 2] = s[2] * (w[i] & 0x30) + bias;
      w_local[4 * i + 3] = s[3] * (w[i] & 0xc0) + bias;
    }
  }

  else if (bits == 3) {
    for (int i = 0; i < (N / 8); i++) {
      w_local += 8 * i;
      w += 3 * i;

      w_local[0] = (w[0] & 0x7) * scale + bias;
      w_local[1] = ((w[0] & 0x38) >> 3) * scale + bias;
      w_local[2] = (((w[0] & 0xc0) >> 6) + ((w[1] & 0x1) << 2)) * scale + bias;
      w_local[3] = ((w[1] & 0xe) >> 1) * scale + bias;
      w_local[4] = ((w[1] & 0x70) >> 4) * scale + bias;
      w_local[5] = (((w[1] & 0x80) >> 7) + ((w[2] & 0x3) << 1)) * scale + bias;
      w_local[6] = ((w[2] & 0x1c) >> 2) * scale + bias;
      w_local[7] = ((w[2] & 0xe0) >> 5) * scale + bias;
    }
  }

  else if (bits == 4) {
    U s[2] = {scale, scale / static_cast<U>(16.0f)};
    for (int i = 0; i < (N / 2); i++) {
      w_local[2 * i] = s[0] * (w[i] & 0x0f) + bias;
      w_local[2 * i + 1] = s[1] * (w[i] & 0xf0) + bias;
    }
  }

  else if (bits == 5) {
    for (int i = 0; i < (N / 8); i++) {
      w_local += 8 * i;
      w += 5 * i;

      w_local[0] = (w[0] & 0x1f) * scale + bias;
      w_local[1] = (((w[0] & 0xe0) >> 5) + ((w[1] & 0x3) << 3)) * scale + bias;
      w_local[2] = ((w[1] & 0x7c) >> 2) * scale + bias;
      w_local[3] = (((w[1] & 0x80) >> 7) + ((w[2] & 0xf) << 1)) * scale + bias;
      w_local[4] = (((w[2] & 0xf0) >> 4) + ((w[3] & 0x1) << 4)) * scale + bias;
      w_local[5] = ((w[3] & 0x3e) >> 1) * scale + bias;
      w_local[6] = (((w[3] & 0xc0) >> 6) + ((w[4] & 0x7) << 2)) * scale + bias;
      w_local[7] = ((w[4] & 0xf8) >> 3) * scale + bias;
    }
  }

  else if (bits == 6) {
    for (int i = 0; i < (N / 4); i++) {
      w_local += 4 * i;
      w += 3 * i;
      w_local[0] = (w[0] & 0x3f) * scale + bias;
      w_local[1] = (((w[0] >> 6) & 0x03) + ((w[1] & 0x0f) << 2)) * scale + bias;
      w_local[2] = (((w[1] >> 4) & 0x0f) + ((w[2] & 0x03) << 4)) * scale + bias;
      w_local[3] = ((w[2] >> 2) & 0x3f) * scale + bias;
    }
  }

  else if (bits == 8) {
    for (int i = 0; i < N; i++) {
      w_local[i] = scale * w[i] + bias;
    }
  }
}

template <
    typename T,
    short BROWS,
    short BCOLS,
    short dst_ld,
    short reduction_dim,
    short tgp_size,
    short group_size,
    short bits>
struct QuantizedBlockLoader {
  static_assert(
      BCOLS <= group_size,
      "The group size should be larger than the columns");
  static_assert(
      group_size % BCOLS == 0,
      "The group size should be divisible by the columns");
  static_assert(
      bits == 2 || bits == 3 || bits == 4 || bits == 5 || bits == 6 ||
          bits == 8,
      "Template undefined for bits not in {2, 3, 4, 5, 6, 8}");

  MLX_MTL_CONST short pack_factor = get_pack_factor<bits, 8>();
  MLX_MTL_CONST short bytes_per_pack = get_bytes_per_pack<bits>();
  MLX_MTL_CONST short BCOLS_PA.6 mtp.* head (same-geometry, same-tokenizer
                pairs only). Validated at submission.

        Returns:
            The created QuantTask.

        Raises:
            ValueError: On invalid inputs or output conflict.
        """
        from ..oq import (
            OQ_DTYPES,
            OQ_LEVELS,
            _validate_oq_dtype_for_model,
            resolve_output_name,
            validate_gemma4_assistant_pair,
            validate_mtp_donor_pair,
        )
        from ..utils.model_loading import _checkpoint_has_mtp_weights

        if oq_level not in OQ_LEVELS:
            raise ValueError(
                f"Invalid oQ level {oq_level}. Must be one of {sorted(OQ_LEVELS)}"
            )
        if dtype not in OQ_DTYPES:
            raise ValueError(f"Invalid dtype {dtype!r}. Must be one of {OQ_DTYPES}")

        source = Path(model_path)
        if not source.exists() or not (source / "config.json").exists():
            raise ValueError(f"Model not found: {model_path}")

        with open(source / "config.json") as f:
            config = json.load(f)
        _validate_oq_dtype_for_model(config, dtype)

        if preserve_mtp and not _checkpoint_has_mtp_weights(source):
            logger.warning(
                "Preserve MTP requested for %s, but no mtp.* tensors were "
                "found in the checkpoint; disabling MTP preservation",
                source.name,
            )
            preserve_mtp = False

        if preserve_mtp and mtp_assistant_model_path:
            raise ValueError(
                "Choose either 'Preserve MTP weights' or 'Combine MTP head', "
                "not both"
            )
        if mtp_assistant_model_path:
            assistant = Path(mtp_assistant_model_path)
            if not assistant.exists() or not (assistant / "config.json").exists():
                raise ValueError(
                    f"Assistant model not found: {mtp_assistant_model_path}"
                )
            with open(assistant / "config.json") as f:
                assistant_config = json.load(f)
            if assistant_config.get("model_type") == "gemma4_assistant":
                validate_gemma4_assistant_pair(config, assistant_config)
            else:
                validate_mtp_donor_pair(source, assistant)
                if _checkpoint_has_mtp_weights(source):
                    logger.warning(
                        "Recipient %s ships its own MTP head; it will be "
                        "stripped and replaced by the donor head from %s",
                        source.name,
                        assistant.name,
                    )

        model_name = source.name
        output_name = resolve_output_name(
            model_name,
            oq_level,
            dtype,
            preserve_mtp=preserve_mtp,
            enhanced=enhanced,
        )
        if mtp_assistant_model_path and not output_name.endswith("-mtp"):
            output_name += "-mtp"
        output_path = self._output_dir / output_name

        if output_path.exists():
            raise ValueError(
                f"Output directory already exists: {output_path}. "
                "Delete it first via the Manager tab."
            )

        # Check for duplicate active tasks (same level + dtype combo)
        for task in self._tasks.values():
            if (
                task.model_path == model_path
                and task.oq_level == oq_level
                and task.dtype == dtype
                and task.enhanced == enhanced
                and task.status in _ACTIVE_STATUSES
            ):
                raise ValueError(
                    f"Quantization for '{model_name}' at oQ{oq_level:g}"
                    f"{'e' if enhanced else ''} "
                    f"({dtype}) is already in progress"
                )

        if enhanced:
            if imatrix_num_samples < 1:
                raise ValueError("imatrix_num_samples must be >= 1")
            if imatrix_seq_length < 1:
                raise ValueError("imatrix_seq_length must be >= 1")
            if not imatrix_    if vm.memoryGuardBreakdown != nil || vm.wiredLimitWarningText != nil {
                ceilingPreviewRow
            }
            Row(
                label: String(localized: "performance.memory.idle_timeout",
                              defaultValue: "Idle Timeout",
                              comment: "Row label for idle timeout field"),
                sublabel: String(localized: "performance.memory.idle_timeout.sub",
                                 defaultValue: "Server-wide auto-unload after N seconds idle. Empty = disabled. Minimum 60.",
                                 comment: "Sublabel for idle timeout")
            ) {
                TextInput(
                    text: $vm.idleTimeoutText,
                    placeholder: String(localized: "performance.memory.idle_timeout.placeholder",
                                        defaultValue: "off",
                                        comment: "Placeholder text for the idle timeout field when disabled"),
                    mono: true,
                    suffix: "s",
                    width: 110
                )
            }
            Row(
                label: String(localized: "performance.memory.model_fallback",
                              defaultValue: "Model Fallback",
                              comment: "Row label for model fallback toggle"),
                sublabel: String(localized: "performance.memory.model_fallback.sub",
                                 defaultValue: "When the requested model isn't loaded, route to any loaded model instead of 404.",
                                 comment: "Sublabel for model fallback toggle"),
                isLast: true
            ) {
                Toggle("", isOn: $vm.modelFallback)
                    .labelsHidden().toggleStyle(.switch)
            }
        }
    }

    /// Effective-ceiling preview + kernel Metal limit warning. Mirrors the
    /// web dashboard's breakdown under the guard tier dropdown: without it
    /// a Custom ceiling above the Metal cap looks accepted while the guard
    /// silently enforces the clamped value (#1463).
    private var ceilingPreviewRow: some View {
        FreeRow {
            VStack(alignment: .leading, spacing: 8) {
                if let breakdown = vm.memoryGuardBreakdown {
                    Text(breakdown)
                        .font(.omlxText(11.5))
                        .foregroundStyle(theme.textSecondary)
                        .fixedSize(horizontal: false, vertical: true)
                }
                if let warning = vm.wiredLimitWarningText {
                    HStack(alignment: .top, spacing: 8) {
                        Image(systemName: "exclamationmark.triangle.fill")
                            .font(.system(size: 12))
                            .foregroundStyle(theme.warningText)
                        VStack(alignment: .leading, spacing: 6) {
                            Text(warning)
                                .font(.omlxText(11))
                                .foregroundStyle(theme.text)
                                .fixedSize(horizontal: false, vertical: true)
                            CodeChip(value: vm.wiredLimitCommand)
                        }
                        Spacer(minLength: 0)
                    }
                    .padding(.horizontal, 10)
                    .padding(.vertical, 8)
                    .background(theme.warningBg)
                    .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
                    .overlay(
                        RoundedRectangle(cornerRadius: 6, style: .continuous)
                            .strokeBorder(theme.warningText.opacity(0.25), lineWidth: 0.5)
                    )
                }
            }
        }
    }
}

// MARK: - Cache

private struct CacheSection: View {
    @Bindable var vm: PerformanceScreenVM

    var body: some View {
        SectionHeader(
            String(localized: "performance.section.cache",
                   defaultValue: "Cache",
                   comment: "Section header for KV cZa-z0-9\\._:-]+\s*\/>/},{begin:a.begin,
"on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{
begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{
beginKeywords:"while if switch catch for"},{
begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",
returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t,
className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t,
relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},
contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,
className:"variable.constant"},E,k,{match:/\$[(.]/}]}}
const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["attached","autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","CKED = BCOLS / pack_factor;
  MLX_MTL_CONST short n_reads =
      (BCOLS_PACKED * BROWS < tgp_size) ? 1 : (BCOLS_PACKED * BROWS) / tgp_size;
  MLX_MTL_CONST short group_steps = group_size / BCOLS;

  const int src_ld;
  const int tile_stride;
  short group_step_cnt;
  const int group_stride;

  const short thread_idx;
  const short bi;
  const short bj;

  threadgroup T* dst;
  const device uint8_t* src;
  const device T* scales;
  const device T* biases;

  QuantizedBlockLoader(
      const device uint8_t* src_,
      const device T* scales_,
      const device T* biases_,
      const int src_ld_,
      threadgroup T* dst_,
      ushort simd_group_id [[simdgroup_index_in_threadgroup]],
      ushort simd_lane_id [[thread_index_in_simdgroup]])
      : src_ld(src_ld_),
        tile_stride(
            reduction_dim ? BCOLS_PACKED * bytes_per_pack
                          : BROWS * src_ld * bytes_per_pack / pack_factor),
        group_step_cnt(0),
        group_stride(BROWS * src_ld / group_size),
        thread_idx(simd_group_id * 32 + simd_lane_id),
        bi(n_reads * thread_idx / BCOLS_PACKED),
        bj((n_reads * thread_idx) % BCOLS_PACKED),
        dst(dst_ + bi * dst_ld + bj * pack_factor),
        src(src_ + bi * src_ld * bytes_per_pack / pack_factor +
            bj * bytes_per_pack),
        scales(scales_ + bi * src_ld / group_size),
        biases(biases_ + bi * src_ld / group_size) {}

  void load_unsafe() const {
    if (BCOLS_PACKED * BROWS < tgp_size && bi >= BROWS) {
      return;
    }

    T scale = *scales;
    T bias = *biases;
    for (int i = 0; i < n_reads; i++) {
      dequantize<T, pack_factor, bits>(
          src + i * bytes_per_pack, scale, bias, dst + i * pack_factor);
    }
  }

  void load_safe(short2 src_tile_dim) const {
    if (BCOLS_PACKED * BROWS < tgp_size && bi >= BROWS) {
      return;
    }

    if (reduction_dim == 1 && bi >= src_tile_dim.x) {
      for (int i = 0; i < n_reads * pack_factor; i++) {
        dst[i] = T(0);
      }
      return;
    }

    if (reduction_dim == 0 && bi >= src_tile_dim.y) {
      for (int i = 0; i < n_reads * pack_factor; i++) {
        dst[i] = T(0);
      }
      return;
    }

    T scale = *scales;
    T bias = *biases;
    for (int i = 0; i < n_reads; i++) {
      dequantize<T, pack_factor, bits>(
          (device uint8_t*)(src + i * bytes_per_pack),
          scale,
          bias,
          dst + i * pack_factor);
    }
  }

  void next() {
    src += tile_stride;
    if (reduction_dim == 1) {
      if (group_steps > 1) {
        group_step_cnt++;
        if (group_step_cnt == group_steps) {
          group_step_cnt = 0;
          scales++;
          biases++;
        }
      } else {
        scales++;
        biases++;
      }
    } else {
      scales += group_stride;
      biases += group_stride;
    }
  }
};

template <typename T, int group_size, int bits, int D>
METAL_FUNC void qmv_quad_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    constant int& in_vec_size,
    const constant int& out_vec_size,
    uint3 tid [[threadgroup_position_in_grid]],
    uint quad_gid [[quadgroup_index_in_threadgroup]],
    uint quad_lid [[thread_index_in_quadgroup]]) {
  constexpr int quads_per_simd = SIMD_SIZE / QUAD_SIZE;
  constexpr int pack_factor = 32 / bits;
  constexpr int values_per_thread = D / QUAD_SIZE;
  constexpr int packs_per_thread = values_per_thread / pack_factor;
  constexpr int scale_step_per_thread = group_size / values_per_thread;
  constexpr int results_per_quadgroup = 8;

  typedef float U;

  thread U x_thread[values_per_thread];
  thread U result[results_per_quadgroup] = {0};

  // Adjust positions
  const int in_vec_size_w = in_vec_size / pack_factor;
  const int in_vec_size_g = in_vec_size / group_size;
  const int out_row = tid.y * quads_per_simd * results_per_quadgroup + quad_gid;

  w += out_row * in_vec_size_w + quad_lid * packs_per_thread;
  scales += out_row * in_vec_size_g + quad_lid / scale_step_per_thread;
  biases += out_row * in_vec_sicache_path:
                digest = hashlib.sha256(str(source.resolve()).encode()).hexdigest()[:12]
                imatrix_cache_path = str(
                    self._output_dir
                    / ".oqe_imatrix"
                    / (
                        f"{model_name}-{digest}-s{int(imatrix_num_samples)}"
                        f"-l{int(imatrix_seq_length)}.npz"
                    )
                )

        source_size = sum(f.stat().st_size for f in source.glob("*.safetensors"))
        if source_size == 0:
            source_size = sum(f.stat().st_size for f in source.glob("*.bin"))

        task_id = str(uuid.uuid4())
        task = QuantTask(
            task_id=task_id,
            model_name=model_name,
            model_path=model_path,
            oq_level=oq_level,
            output_name=output_name,
            output_path=str(output_path),
            source_size=source_size,
            group_size=group_size,
            sensitivity_model_path=sensitivity_model_path,
            text_only=text_only,
            dtype=dtype,
            preserve_mtp=preserve_mtp,
            auto_proxy_sensitivity=auto_proxy_sensitivity,
            enhanced=enhanced,
            imatrix_cache_path=imatrix_cache_path,
            imatrix_reuse_cache=imatrix_reuse_cache,
            imatrix_strict=imatrix_strict,
            imatrix_num_samples=imatrix_num_samples,
            imatrix_seq_length=imatrix_seq_length,
            mtp_assistant_model_path=mtp_assistant_model_path,
        )
        self._tasks[task_id] = task

        self._active_tasks[task_id] = asyncio.create_task(
            self._run_quantization(task_id)
        )

        logger.info(
            f"oQ quantization queued: {model_name} -> "
            f"oQ{oq_level:g}{'e' if enhanced else ''} "
            f"(task_id={task_id})"
        )
        return task

    async def cancel_quantization(self, task_id: str) -> bool:
        """Cancel an active quantization task."""
        task = self._tasks.get(task_id)
        if task is None:
            return False
        if task.status not in _ACTIVE_STATUSES:
            return False

        self._cancelled.add(task_id)
        task.status = QuantStatus.CANCELLED

        progress_task = self._progress_tasks.pop(task_id, None)
        if progress_task and not progress_task.done():
            progress_task.cancel()

        active_task = self._active_tasks.pop(task_id, None)

        # Clean up partial output
        output = Path(task.output_path)
        if output.exists():
            import shutil

            shutil.rmtree(output, ignore_errors=True)

        # Wait for the quantization thread to actually finish.
        # Do NOT call active_task.cancel() first — that only cancels the
        # asyncio wrapper and causes the await to return immediately while
        # the OS thread continues running Metal commands. Instead, rely on
        # cooperative cancellation: the progress callback raises
        # _QuantCancelled when it sees the flag, terminating quantize_oq
        # at the next callback point (per-layer in GPTQ, per-tensor in
        # streaming).
        if active_task and not active_task.done():
            try:
                await asyncio.wait_for(
                    asyncio.shield(active_task),
                    timeout=30.0,
                )
            except asyncio.TimeoutError:
                # Thread didn't exit cooperatively (e.g. stuck in long GPTQ
                # block). Force-cancel as last resort and wait a bit for
                # Metal to settle.
                logger.warning(
                    "oQ cancel: cooperative exit timed out, force-cancelling"
                )
                active_task.cancel()
                try:
                    await active_task
                except (asyncio.CancelledError, Exception):
                    pass
                await asyncio.sleep(2.0)
            except (asyncio.CancelledError, Exception):
                pass

        # GPU cleanup after thread is done
        if HAS_MLX:
            for _attemptache settings"),
            subtitle: String(localized: "performance.section.cache.sub",
                             defaultValue: "KV cache spillover. The master switch gates everything below.",
                             comment: "Subtitle for the Cache section")
        )

        ListGroup {
            Row(
                label: String(localized: "performance.cache.enabled",
                              defaultValue: "Cache Enabled",
                              comment: "Row label for the master cache enable toggle"),
                sublabel: String(localized: "performance.cache.enabled.sub",
                                 defaultValue: "Master switch for the engine's KV cache subsystem.",
                                 comment: "Sublabel for the master cache enable toggle")
            ) {
                Toggle("", isOn: $vm.cacheEnabled)
                    .labelsHidden().toggleStyle(.switch)
            }
            Row(
                label: String(localized: "performance.cache.hot_only",
                              defaultValue: "Hot Cache Only",
                              comment: "Row label for the hot cache only toggle"),
                sublabel: String(localized: "performance.cache.hot_only.sub",
                                 defaultValue: "Skip SSD spillover. Useful on fast machines with abundant RAM.",
                                 comment: "Sublabel for hot cache only toggle")
            ) {
                Toggle("", isOn: $vm.hotCacheOnly)
                    .labelsHidden().toggleStyle(.switch)
                    .disabled(!vm.cacheEnabled)
            }
            Row(
                label: String(localized: "performance.cache.hot_size",
                              defaultValue: "Hot Cache Size",
                              comment: "Row label for the hot cache size field"),
                sublabel: String(localized: "performance.cache.hot_size.sub",
                                 defaultValue: "RAM ceiling for hot cache. \"0\" disables, sizes like \"8GB\" are accepted.",
                                 comment: "Sublabel describing accepted hot cache size values")
            ) {
                TextInput(
                    text: $vm.hotCacheMaxSize,
                    placeholder: "0",
                    mono: true,
                    width: 140
                )
                .disabled(!vm.cacheEnabled)
            }
            Row(
                label: String(localized: "performance.cache.ssd_dir",
                              defaultValue: "SSD Cache Directory",
                              comment: "Row label for the SSD cache directory field"),
                sublabel: String(localized: "performance.cache.ssd_dir.sub",
                                 defaultValue: "Where cold-spillover blocks live. Empty = base_path/cache.",
                                 comment: "Sublabel for the SSD cache directory")
            ) {
                TextInput(
                    text: $vm.ssdCacheDir,
                    placeholder: "<base_path>/cache",
                    mono: true,
                    width: 280
                )
                .disabled(!vm.cacheEnabled || vm.hotCacheOnly)
            }
            Row(
                label: String(localized: "performance.cache.ssd_size",
                              defaultValue: "SSD Cache Size",
                              comment: "Row label for the SSD cache size field"),
                sublabel: String(localized: "performance.cache.ssd_size.sub",
                                 defaultValue: "Cold-spillover ceiling. \"auto\" = 10% of SSD capacity.",
                                 comment: "Sublabel describing accepted SSD cache size values")
            ) {
                TextInput(
                    text: $vm.ssdCacheMaxSize,
                    placeholder: String(localized: "performance.memory.placeholder_auto",
                                        defaultValue: "auto",
                                        comment: "Memory field placeholder meaning automatic"),
        warn_unqualified_access"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"]
;var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={
begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]}
;Object.assign(t,{className:"variable",variants:[{
begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={
className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={
begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,
end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/,
contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$?\(\(/,
end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t]
},l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10
}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,
contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{
name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/,
keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"],
literal:["true","false"],
built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"]
},contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{
match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}},
grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}]
}),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={
className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{
match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{
begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{
begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",
end:"'",illegal:"."},e.END_SAME_AS_BEGIN({
begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={
className:"number",variants:[{begin:"\\b(0b[01']+)"},{
begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"
},{
begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
}],relevance:0}ze_g + quad_lid / scale_step_per_thread;
  x += tid.x * in_vec_size + quad_lid * values_per_thread;
  y += tid.x * out_vec_size + out_row;

  U sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);

  for (int row = 0; row < results_per_quadgroup; row++) {
    auto wl = (const device uint8_t*)(w + row * in_vec_size_w * quads_per_simd);
    const device T* sl = scales + row * in_vec_size_g * quads_per_simd;
    const device T* bl = biases + row * in_vec_size_g * quads_per_simd;

    U s = sl[0];
    U b = bl[0];
    if (row * quads_per_simd + out_row < out_vec_size) {
      result[row] += qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
    }
  }

  for (int row = 0; row < results_per_quadgroup; row++) {
    result[row] = quad_sum(result[row]);
    if (quad_lid == 0 && row * quads_per_simd + out_row < out_vec_size) {
      y[row * quads_per_simd] = static_cast<T>(result[row]);
    }
  }
}

template <typename T, int group_size, int bits>
METAL_FUNC void qmv_fast_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  constexpr int packs_per_thread = bits == 2 ? 1 : 2;
  constexpr int num_simdgroups = 2;
  constexpr int results_per_simdgroup = 4;
  constexpr int pack_factor = get_pack_factor<bits, 32>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits, 32>();
  constexpr int values_per_thread = pack_factor * packs_per_thread;
  constexpr int block_size = values_per_thread * SIMD_SIZE;
  constexpr int scale_step_per_thread = group_size / values_per_thread;

  const device uint8_t* ws = (const device uint8_t*)w;

  typedef float U;

  thread U x_thread[values_per_thread];
  thread U result[results_per_simdgroup] = {0};

  // Adjust positions
  const int in_vec_size_w = in_vec_size * bytes_per_pack / pack_factor;
  const int in_vec_size_g = in_vec_size / group_size;
  const int out_row = tid.y * (num_simdgroups * results_per_simdgroup) +
      simd_gid * results_per_simdgroup;

  ws += out_row * in_vec_size_w + simd_lid * packs_per_thread * bytes_per_pack;
  scales += out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
  biases += out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
  x += tid.x * in_vec_size + simd_lid * values_per_thread;
  y += tid.x * out_vec_size + out_row;

  for (int k = 0; k < in_vec_size; k += block_size) {
    U sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);

    for (int row = 0; row < results_per_simdgroup; row++) {
      auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
      const device T* sl = scales + row * in_vec_size_g;
      const device T* bl = biases + row * in_vec_size_g;

      U s = sl[0];
      U b = bl[0];
      result[row] += qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
    }

    ws += block_size * bytes_per_pack / pack_factor;
    scales += block_size / group_size;
    biases += block_size / group_size;
    x += block_size;
  }

  for (int row = 0; row < results_per_simdgroup; row++) {
    result[row] = simd_sum(result[row]);
    if (simd_lid == 0) {
      y[row] = static_cast<T>(result[row]);
    }
  }
}

template <typename T, int group_size, int bits>
METAL_FUNC void qmv_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    const constant int& in_vec_size,
    const constant int& out_vec_size,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  constexpr int num_simdgroups = 2;
  constexpr int results_per_simdgroup = 4;
  constexpr int packs_per_thread = 1;
  constexpr int pack_factor = get_pack_factor<bits, 32>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits, 32>();

  constexpr int values_per_thread = in range(3):
                try:
                    mx.synchronize()
                    mx.clear_cache()
                    break
                except Exception:
                    await asyncio.sleep(1.0)

        logger.info(f"oQ quantization cancelled: {task.model_name} (task_id={task_id})")
        return True

    def remove_task(self, task_id: str) -> bool:
        """Remove a completed/failed/cancelled task from the list."""
        task = self._tasks.get(task_id)
        if task is None:
            return False
        if task.status in _ACTIVE_STATUSES:
            return False
        del self._tasks[task_id]
        self._cancelled.discard(task_id)
        return True

    def get_tasks(self) -> list[dict]:
        """Return all tasks as serializable dicts."""
        return [t.to_dict() for t in self._tasks.values()]

    @property
    def is_quantizing(self) -> bool:
        """Check if any quantization task is actively running."""
        return any(t.status in _ACTIVE_STATUSES for t in self._tasks.values())

    async def shutdown(self) -> None:
        """Cancel all active tasks."""
        for task_id in list(self._active_tasks):
            await self.cancel_quantization(task_id)

    async def _run_quantization(self, task_id: str) -> None:
        """Execute the quantization pipeline in background."""
        task = self._tasks[task_id]
        try:
            async with self._quant_sem:
                if task_id in self._cancelled:
                    return

                # Ensure GPU is clean before starting (previous task may have been cancelled)
                # Metal command buffers need full sync + cache clear after cancellation
                if HAS_MLX:
                    for _ in range(3):
                        try:
                            mx.synchronize()
                            mx.clear_cache()
                            break
                        except Exception:
                            await asyncio.sleep(1.0)

                # Phase 1: Loading
                task.status = QuantStatus.LOADING
                task.started_at = time.time()
                task.phase = "Loading model..."
                task.progress = 5.0

                def _progress_cb(
                    phase: str,
                    pct: float,
                    detail: str = "",
                    meta: dict | None = None,
                ) -> None:
                    if task_id in self._cancelled:
                        raise _QuantCancelled(f"Task {task_id} cancelled")
                    base_phase = phase.split("|", 1)[0]
                    if base_phase.startswith("quantizing"):
                        task.status = QuantStatus.QUANTIZING
                    elif base_phase == "saving":
                        task.status = QuantStatus.SAVING
                    else:
                        task.status = QuantStatus.LOADING
                    task.phase = self._phase_label(phase, task.oq_level, task.enhanced)
                    task.progress_detail = detail or ""
                    task.progress_meta = meta or {}
                    task.progress = pct
                    task._last_progress_callback_at = time.time()

                # Start time-based progress estimation
                self._progress_tasks[task_id] = asyncio.create_task(
                    self._estimate_progress(task_id)
                )

                from ..oq import quantize_oq_streaming

                await asyncio.to_thread(
                    quantize_oq_streaming,
                    task.model_path,
                    task.output_path,
                    task.oq_level,
                    task.group_size,
                    _progress_cb,
                    task.text_only,
                    None,  # target_bpw
                    None,  # hard_cap_bpw
                    task.sensitivity_model_path,
                    task.dtype,
                    task.preserve_mtp,
                    task.auto_proxy_sensitivity,
                    enhanced=task.enhanced,
                          mono: true,
                    width: 140
                )
                .disabled(!vm.cacheEnabled || vm.hotCacheOnly)
            }
            Row(
                label: String(localized: "performance.cache.initial_blocks",
                              defaultValue: "Initial Cache Blocks",
                              comment: "Row label for the initial cache blocks field"),
                sublabel: String(localized: "performance.cache.initial_blocks.sub",
                                 defaultValue: "Pre-allocated cache blocks at server start. Requires restart to apply.",
                                 comment: "Sublabel for the initial cache blocks field"),
                isLast: true
            ) {
                TextInput(
                    text: $vm.initialCacheBlocksText,
                    placeholder: String(localized: "performance.memory.placeholder_auto",
                                        defaultValue: "auto",
                                        comment: "Memory field placeholder meaning automatic"),
                    mono: true,
                    width: 110
                )
                .disabled(!vm.cacheEnabled)
            }
        }
    }
}


# ===== FILE: apps/omlx-mac/Sources/AppView/Screens/ProfileViews.swift =====

// Visual components used by the Profiles tab and the Server-defaults block
// on the Server screen. The shapes mirror omlx-screens.jsx:626-1191:
//
//   • ProfileGroup        — chip row labelled by scope
//   • ActiveProfileBanner — top-of-tab summary of the model's attach state
//   • SaveAsPopover       — inline name + scope toggle for "Save as new"
//   • ProfileDetailCard   — visual summary of one profile's settings
//
// The view models live elsewhere — this file is render-only.

import SwiftUI

// MARK: - Scope colors / labels

/// Per-scope visual treatment. Lifted from omlx-screens.jsx:878-884
/// (SCOPE_META) so the chip dots and badges read the same as the canvas.
enum ProfileScopeMeta {
    static func color(_ scope: ProfileScope, theme: OMLXTheme) -> Color {
        switch scope {
        case .preset: return theme.amberDot
        case .global: return Color(rgb24: 0xAF52DE)
        case .model:  return theme.blueDot
        }
    }

    static func label(_ scope: ProfileScope) -> String {
        switch scope {
        case .preset: return String(localized: "profile.scope.preset",
                                    defaultValue: "Preset",
                                    comment: "Scope label for shipped preset profiles in Profiles tab")
        case .global: return String(localized: "profile.scope.global",
                                    defaultValue: "Global",
                                    comment: "Scope label for user-defined global profiles")
        case .model:  return String(localized: "profile.scope.model",
                                    defaultValue: "Model",
                                    comment: "Scope label for per-model profiles")
        }
    }
}

// MARK: - ProfileGroup

/// One chip row, scoped to preset / global / model. The active chip
/// (when its scope matches `activeName`) renders in scope color; the
/// "based-on of the working profile" gets a dashed scope-color border;
/// preview-selected gets a 1px primary-text border.
struct ProfileGroup: View {
    let scope: ProfileScope
    let label: String
    let names: [String]
    /// Name of the currently-active profile in this scope (or nil if the
    /// active profile lives in a different scope).
    let activeName: String?
    /// Name of the profile the working profile forked from (or nil).
    let basedOnName: String?
    /// Name of the profile currently being previewed in the detail card.
    let previewName: String?
    let canSaveCurrent: Bool

    let onSelect: (String) -> Void
    let onSaveCurrent: () -> Void
    /// Optional refresh affordance — when non-nil, a small refresh icon
    /// renders in the header instead of (or alongside) the save button.
    /// Used by the preset chip strip to pull the latest bundle fro,c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{
keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"
},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{
className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={
className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0
},g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={
keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"],
type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"],
literal:"true false NULL",
built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr"
},b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{
begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],
keywords:u,contains:b.concat([{begin:/\(/,end:/\)/,keywords:u,
contains:b.concat(["self"]),relevance:0}]),relevance:0},p={
begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,
keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{
begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})],
relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,
keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,
end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]
}]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u,
disableAutodetect:!0,illegal:"</",contains:[].concat(m,p,b,[c,{
begin:e.IDENT_RE+"::",keywords:u},{className:"class",
beginKeywords:"enum class struct union",end:/[{;:<>=]/,contains:[{
beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c,
strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{
contains:[{begin:/\\\n/}]
}),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={
className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{
begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{
begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",
end:"'",illegal:"."},e.END_SAME_AS_BEGIN({
begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={
className:"number",variants:[{begin:"\\b(0b[01']+)"},{
begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"
},{
begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
}],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{
keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"
},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{
className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={
className:"title",begin:n.optional(i)+e.IDENT_RE,r pack_factor * packs_per_thread;
  constexpr int block_size = values_per_thread * SIMD_SIZE;
  constexpr int scale_step_per_thread = group_size / values_per_thread;

  const device uint8_t* ws = (const device uint8_t*)w;

  typedef float U;

  thread U x_thread[values_per_thread];
  thread U result[results_per_simdgroup] = {0};

  // Adjust positions
  const int in_vec_size_w = in_vec_size * bytes_per_pack / pack_factor;
  const int in_vec_size_g = in_vec_size / group_size;
  const int out_row = tid.y * (num_simdgroups * results_per_simdgroup) +
      simd_gid * results_per_simdgroup;
  const int used_out_row = min(out_vec_size - results_per_simdgroup, out_row);

  if (out_row >= out_vec_size) {
    return;
  }

  // In this case we need to properly guard all our reads because there isn't
  // even 1 tile in the matrix
  if (out_vec_size < (num_simdgroups * results_per_simdgroup)) {
    ws +=
        out_row * in_vec_size_w + simd_lid * packs_per_thread * bytes_per_pack;
    scales += out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
    biases += out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
    x += tid.x * in_vec_size + simd_lid * values_per_thread;
    y += tid.x * out_vec_size + out_row;

    int k = 0;
    for (; k < in_vec_size - block_size; k += block_size) {
      U sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);

      for (int row = 0;
           row < results_per_simdgroup && out_row + row < out_vec_size;
           row++) {
        auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
        const device T* sl = scales + row * in_vec_size_g;
        const device T* bl = biases + row * in_vec_size_g;

        U s = sl[0];
        U b = bl[0];
        result[row] +=
            qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
      }

      ws += block_size * bytes_per_pack / pack_factor;
      scales += block_size / group_size;
      biases += block_size / group_size;
      x += block_size;
    }
    const int remaining = clamp(
        static_cast<int>(in_vec_size - k - simd_lid * values_per_thread),
        0,
        values_per_thread);
    if (remaining > 0) {
      U sum = load_vector_safe<T, U, values_per_thread, bits>(
          x, x_thread, remaining);

      for (int row = 0;
           row < results_per_simdgroup && out_row + row < out_vec_size;
           row++) {
        auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
        const device T* sl = scales + row * in_vec_size_g;
        const device T* bl = biases + row * in_vec_size_g;

        U s = sl[0];
        U b = bl[0];
        result[row] += qdot_safe<U, values_per_thread, bits>(
            wl, x_thread, s, b, sum, remaining);
      }
    }

    for (int row = 0;
         row < results_per_simdgroup && out_row + row < out_vec_size;
         row++) {
      result[row] = simd_sum(result[row]);
      if (simd_lid == 0) {
        y[row] = static_cast<T>(result[row]);
      }
    }
  }

  // In this case the last tile is moved back to redo some output values
  else {
    ws += used_out_row * in_vec_size_w +
        simd_lid * packs_per_thread * bytes_per_pack;
    scales += used_out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
    biases += used_out_row * in_vec_size_g + simd_lid / scale_step_per_thread;
    x += tid.x * in_vec_size + simd_lid * values_per_thread;
    y += tid.x * out_vec_size + used_out_row;

    int k = 0;
    for (; k < in_vec_size - block_size; k += block_size) {
      U sum = load_vector<T, U, values_per_thread, bits>(x, x_thread);

      for (int row = 0; row < results_per_simdgroup; row++) {
        auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
        const device T* sl = scales + row * in_vec_size_g;
        const device T* bl = biases + row * in_vec_size_g;

        U s = sl[0];
        U b = bl[0];
        result[row] +=
            qdot<U, values_per_thread, bits>(wl, x_thread, s, b, sum);
      }

      ws += block_size * bytes_per_pack / pack_factor;
      scales += block_size / group_size;
      biases += block_size /       imatrix_cache_path=task.imatrix_cache_path,
                    imatrix_reuse_cache=task.imatrix_reuse_cache,
                    imatrix_strict=task.imatrix_strict,
                    imatrix_num_samples=task.imatrix_num_samples,
                    imatrix_seq_length=task.imatrix_seq_length,
                )

                if task_id in self._cancelled:
                    return

                if task.mtp_assistant_model_path:
                    from ..oq import combine_mtp_into_output

                    _progress_cb("saving", 97.0, "Merging MTP head...")
                    await asyncio.to_thread(
                        combine_mtp_into_output,
                        task.output_path,
                        task.mtp_assistant_model_path,
                    )

                if task_id in self._cancelled:
                    return

                # Complete
                task.status = QuantStatus.COMPLETED
                task.progress = 100.0
                task.phase = "Completed"
                task.progress_detail = ""
                task.progress_meta = {}
                task.completed_at = time.time()
                task.output_size = _dir_size(Path(task.output_path))

                elapsed = task.completed_at - task.started_at
                logger.info(
                    f"oQ quantization completed: {task.output_name} "
                    f"({elapsed:.0f}s, {_format_size(task.output_size)})"
                )

                if self._on_complete:
                    try:
                        result = self._on_complete()
                        if asyncio.iscoroutine(result):
                            await result
                    except Exception:
                        logger.exception("on_complete callback failed")

        except asyncio.CancelledError:
            if task.status not in (QuantStatus.CANCELLED, QuantStatus.FAILED):
                task.status = QuantStatus.CANCELLED
        except _QuantCancelled:
            if task.status != QuantStatus.CANCELLED:
                task.status = QuantStatus.CANCELLED
        except Exception as e:
            if task_id not in self._cancelled:
                task.status = QuantStatus.FAILED
                task.error = str(e)
                task.completed_at = time.time()
                logger.exception(f"oQ quantization failed: {task.model_name} -> {e}")
                # Clean up partial output
                output = Path(task.output_path)
                if output.exists():
                    import shutil

                    shutil.rmtree(output, ignore_errors=True)
        finally:
            pt = self._progress_tasks.pop(task_id, None)
            if pt and not pt.done():
                pt.cancel()
            self._active_tasks.pop(task_id, None)

    async def _estimate_progress(self, task_id: str) -> None:
        """Estimate progress by time during quantize phase (30-90%)."""
        task = self._tasks.get(task_id)
        if task is None:
            return

        source_gb = max(task.source_size / (1024**3), 0.1)
        estimated_total = source_gb * 3.0
        start = time.time()

        try:
            while task_id not in self._cancelled and task.status in _ACTIVE_STATUSES:
                await asyncio.sleep(2)
                elapsed = time.time() - start
                if time.time() - getattr(task, "_last_progress_callback_at", 0.0) < 5:
                    continue
                if task.status == QuantStatus.QUANTIZING:
                    if self._has_explicit_quant_progress(task):
                        continue
                    fraction = min(elapsed / estimated_total, 0.95)
                    task.progress = max(task.progress, 30.0 + fraction * 60.0)
                elif task.status == QuantStatus.SAVING:
                    # During save, poll output dir size
                    output = Path(task.output_path)
                    if output.exists() and task.source_size > 0:
                        current = _dir_size(output)
                        # Estimate output m
    /// omlx.ai via `POST /api/presets/refresh`.
    var onRefresh: (() -> Void)? = nil
    /// Spinner state for the refresh icon. Disables the button while a
    /// refresh is in flight so a fast user can't queue duplicates.
    var isRefreshing: Bool = false
    /// Optional inline-rename callback. When provided, double-clicking a
    /// chip swaps its label for a `TextField`; Enter commits via
    /// `(originalName, newName)`. Pass nil for read-only groups (preset
    /// chips backed by the shipped JSON bundle).
    var onRename: ((String, String) -> Void)? = nil

    @Environment(\.omlxTheme) private var theme
    @State private var renamingName: String? = nil
    @State private var renameText: String = ""
    @FocusState private var renameFieldFocused: Bool

    var body: some View {
        VStack(alignment: .leading, spacing: 6) {
            header
            chipRow
        }
        .padding(.horizontal, 14)
        .padding(.bottom, 12)
    }

    @ViewBuilder
    private var header: some View {
        HStack(spacing: 8) {
            Circle()
                .fill(ProfileScopeMeta.color(scope, theme: theme))
                .frame(width: 6, height: 6)
            Text(label)
                .font(.omlxText(10.5, weight: .heavy))
                .kerning(0.7)
                .textCase(.uppercase)
                .foregroundStyle(theme.textSecondary)
            Spacer(minLength: 8)
            if let onRefresh {
                Button {
                    onRefresh()
                } label: {
                    Image(systemName: isRefreshing
                          ? "arrow.triangle.2.circlepath"
                          : "arrow.clockwise")
                        .font(.system(size: 11, weight: .semibold))
                        .symbolEffect(.rotate, isActive: isRefreshing)
                }
                .buttonStyle(.omlx(.plain, size: .small))
                .help(String(localized: "profile.group.refresh.help",
                             defaultValue: "Refresh presets from omlx.ai",
                             comment: "Tooltip on the refresh button in the preset chip group header"))
                .disabled(isRefreshing)
            }
            if canSaveCurrent {
                Button {
                    onSaveCurrent()
                } label: {
                    Label(String(localized: "profile.group.save_current_as_new",
                                 defaultValue: "Save current as new",
                                 comment: "Button in profile chip-group header that saves the working profile as a new named profile"),
                          systemImage: "plus")
                        .labelStyle(.titleAndIcon)
                        .font(.omlxText(11, weight: .medium))
                }
                .buttonStyle(.omlx(.plain, size: .small))
                .overlay(
                    Capsule().strokeBorder(
                        theme.inputBorder, style: StrokeStyle(lineWidth: 1, dash: [3, 2])
                    )
                )
                .foregroundStyle(theme.textSecondary)
            }
        }
        .padding(.horizontal, 2)
    }

    @ViewBuilder
    private var chipRow: some View {
        let metaColor = ProfileScopeMeta.color(scope, theme: theme)
        Group {
            if names.isEmpty {
                Text(String(localized: "profile.group.empty",
                            defaultValue: "No \(ProfileScopeMeta.label(scope).lowercased()) profiles yet.",
                            comment: "Placeholder text in an empty profile chip group; placeholder is the lowercased scope name"))
                    .font(.omlxText(11.5))
                    .foregroundStyle(theme.textTertiary)
                    .padding(.vertical, 10)
                    .padding(.horizontal, 12)
            } else {
                FlowLayout(spacing: 6) {
                    ForEach(names, id: \.self) { name in
                        chip(name: name, metaColor: metaColor)
                    }
                }
                .padding(.vertical, 8)
elevance:0
},g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={
type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"],
keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"],
literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"],
_type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"]
},b={className:"function.dispatch",relevance:0,keywords:{
_hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"]
},
begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/))
},m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{
begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],
keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u,
contains:m.concat(["self"]),relevance:0}]),relevance:0},_={className:"function",
begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,
keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{
begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{
begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{
className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0,
contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u,
relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}]
},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++",
aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"</",
classNameAliases:{"function.dispatch":"built_in"},
contains:[].concat(p,_,b,m,[c,{
begin:"\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multisetgroup_size;
      x += block_size;
    }
    const int remaining = clamp(
        static_cast<int>(in_vec_size - k - simd_lid * values_per_thread),
        0,
        values_per_thread);
    if (remaining > 0) {
      U sum = load_vector_safe<T, U, values_per_thread, bits>(
          x, x_thread, remaining);

      for (int row = 0; row < results_per_simdgroup; row++) {
        auto wl = (const device uint8_t*)(ws + row * in_vec_size_w);
        const device T* sl = scales + row * in_vec_size_g;
        const device T* bl = biases + row * in_vec_size_g;

        U s = sl[0];
        U b = bl[0];
        result[row] += qdot_safe<U, values_per_thread, bits>(
            wl, x_thread, s, b, sum, remaining);
      }
    }
    for (int row = 0; row < results_per_simdgroup; row++) {
      result[row] = simd_sum(result[row]);
      if (simd_lid == 0) {
        y[row] = static_cast<T>(result[row]);
      }
    }
  }
}

template <typename T, const int group_size, const int bits>
METAL_FUNC void qvm_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    const int in_vec_size,
    const int out_vec_size,
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  constexpr int power_of_2_bits = (bits & (bits - 1)) == 0;
  constexpr int num_simdgroups = 2;
  constexpr int pack_factor = get_pack_factor<bits, 32>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();

  constexpr int tn = 32 / pack_factor;
  constexpr int block_size = SIMD_SIZE;

  using W_T =
      typename ConditionalType<power_of_2_bits, uint32_t, uint8_t>::type;
  const device W_T* ws = (const device W_T*)w;

  typedef float U;
  typedef struct {
    W_T wi[tn * bytes_per_pack];
  } vec_w;

  thread vec_w w_local;
  thread U result[tn * pack_factor] = {0};
  thread U scale = 1;
  thread U bias = 0;
  thread U x_local = 0;

  // Adjust positions
  const int out_vec_size_w = out_vec_size * bytes_per_pack / pack_factor;
  const int out_vec_size_g = out_vec_size / group_size;
  int out_col = pack_factor * tn * (tid.y * num_simdgroups + simd_gid);
  ws += out_col * bytes_per_pack / pack_factor + simd_lid * out_vec_size_w;
  scales += out_col / group_size + simd_lid * out_vec_size_g;
  biases += out_col / group_size + simd_lid * out_vec_size_g;
  x += tid.x * in_vec_size + simd_lid;
  y += tid.x * out_vec_size + out_col;

  if (out_col >= out_vec_size) {
    return;
  }

  // Loop over in_vec in blocks of block_size
  int remaining = in_vec_size % block_size;
  if (remaining == 0) {
    for (int i = 0; i < in_vec_size; i += block_size) {
      x_local = *x;
      scale = *scales;
      bias = *biases;
      w_local = *((device vec_w*)ws);
      qouter<U, tn * pack_factor, bits>(
          (thread uint8_t*)&w_local, x_local, scale, bias, result);

      x += block_size;
      scales += block_size * out_vec_size_g;
      biases += block_size * out_vec_size_g;
      ws += block_size * out_vec_size_w;
    }
  } else {
    for (int i = block_size; i < in_vec_size; i += block_size) {
      x_local = *x;
      scale = *scales;
      bias = *biases;
      w_local = *((device vec_w*)ws);

      qouter<U, tn * pack_factor, bits>(
          (thread uint8_t*)&w_local, x_local, scale, bias, result);

      x += block_size;
      scales += block_size * out_vec_size_g;
      biases += block_size * out_vec_size_g;
      ws += block_size * out_vec_size_w;
    }
    if (static_cast<int>(simd_lid) < remaining) {
      x_local = *x;
      scale = *scales;
      bias = *biases;
      w_local = *((device vec_w*)ws);
    } else {
      x_local = 0;
      scale = 0;
      bias = 0;
    }
    qouter<U, tn * pack_factor, bits>(
        (thread uint8_t*)&w_local, x_local, scale, bias, result);
  }

// Accumulate in the simdgroup
#pragma clang loop unroll(full)
  for (int k = 0; k < tn * pack_factor; k++) {
    result[k] = simd_sum(result[k]);
  }

  // Store the result
  if (simd_lid == 0) {
#pragma clang loop unroas source * (oq_level / 16)
                        expected = task.source_size * task.oq_level / 16
                        if expected > 0:
                            save_frac = min(current / expected, 0.99)
                            task.progress = max(task.progress, 90.0 + save_frac * 10.0)
        except asyncio.CancelledError:
            pass

    @staticmethod
    def _has_explicit_quant_progress(task: QuantTask) -> bool:
        """Return True once the quantizer emits byte-level progress."""
        meta = task.progress_meta if isinstance(task.progress_meta, dict) else {}
        try:
            total_bytes = int(meta.get("total_bytes") or 0)
            processed_bytes = int(meta.get("processed_bytes") or 0)
        except (TypeError, ValueError):
            return False
        return total_bytes > 0 and processed_bytes >= 0

    @staticmethod
    def _phase_label(phase: str, oq_level: float, enhanced: bool = False) -> str:
        """Human-readable phase label."""
        oq_label = f"oQ{oq_level:g}{'e' if enhanced else ''}"
        labels = {
            "loading": "Loading model...",
            "imatrix": "Collecting oQe imatrix...",
            "quantizing": f"Quantizing to {oq_label}...",
            "saving": "Saving quantized model...",
        }
        # Handle progress: "quantizing_eta|792|879|0:02"
        if phase.startswith("quantizing_eta|"):
            parts = phase.split("|")
            current = parts[1] if len(parts) > 1 else "?"
            total = parts[2] if len(parts) > 2 else "?"
            eta = parts[3] if len(parts) > 3 and parts[3] else ""
            pct = (
                int(int(current) / max(int(total), 1) * 100)
                if current.isdigit() and total.isdigit()
                else 0
            )
            label = f"{oq_label}: {pct}%"
            if eta:
                label += f" ({eta} remaining)"
            return label
        return labels.get(phase, phase)


# ===== FILE: omlx/admin/routes.py =====

# SPDX-License-Identifier: Apache-2.0
"""Admin panel routes for oMLX server configuration.

This module provides HTTP routes for the admin panel including:
- Login/logout with API key authentication
- Dashboard for server monitoring
- Model settings management (per-model sampling parameters, pinning, default)
- Global settings management
"""

import asyncio
import inspect
import json
import logging
import os
import re
import shutil
import signal
import sys
import time
from collections import deque
from dataclasses import asdict, is_dataclass
from datetime import UTC, datetime
from pathlib import Path
from typing import Any, Literal, Optional

import requests
from fastapi import APIRouter, Depends, HTTPException, Request, Response
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel, Field

from ..api.markitdown import MARKITDOWN_MODEL_ID, markitdown_model_visible
from ..api.openai_models import _coerce_tool_call_arguments
from ..api.utils import _try_parse_json
from ..model_profiles import EXCLUDED_FROM_PROFILES
from ..model_settings import merge_chat_template_kwargs
from ..settings import BURST_DECODE_MODES, SubKeyEntry, burst_decode_env
from ..utils.release_check import normalize_update_channel, select_latest_release
from .auth import (
    REMEMBER_ME_MAX_AGE,
    SESSION_MAX_AGE,
    compare_keys,
    create_session_token,
    require_admin,
    validate_api_key,
    verify_api_key,
    verify_session,
)

logger = logging.getLogger(__name__)

PRESET_REMOTE_URL = "https://omlx.ai/assets/omlx_preset.json"


# =============================================================================
# Pydantic Models
# =============================================================================


class LoginRequest(BaseModel):
    """Request model for admin login."""

    api_key: str
    remember: bool = False


class SetupApiKeyRequest(BaseModel):
    """Request model for initial API key setup."""

    api_key: str
    api_key_confirm: str


class Cr                .padding(.horizontal, 10)
            }
        }
        // The chip row needs to span its container's width so FlowLayout
        // receives a definite width proposal — without this the layout's
        // two passes (sizeThatFits with .unspecified, then placeSubviews
        // with the parent's bounds) disagree on wrap count and chips
        // overflow into the next group's header. `.background` (vs the
        // old ZStack) keeps the rounded surface flush to the same frame.
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(
            RoundedRectangle(cornerRadius: 10, style: .continuous)
                .fill(theme.groupBg)
        )
        .overlay(
            RoundedRectangle(cornerRadius: 10, style: .continuous)
                .strokeBorder(theme.groupBorder, lineWidth: 0.5)
        )
    }

    @ViewBuilder
    private func chip(name: String, metaColor: Color) -> some View {
        let isActive = (activeName == name)
        let isBase = (basedOnName == name)
        let isPreviewed = (previewName == name)
        let isEditing = (renamingName == name)
        HStack(spacing: 5) {
            if isActive && !isEditing {
                Image(systemName: "checkmark")
                    .font(.system(size: 10, weight: .bold))
                    .foregroundStyle(.white)
            }
            if isEditing {
                TextField("", text: $renameText)
                    .textFieldStyle(.plain)
                    .font(.omlxText(12, weight: .medium))
                    .foregroundStyle(isActive ? .white : theme.text)
                    .fixedSize(horizontal: true, vertical: false)
                    .focused($renameFieldFocused)
                    .onSubmit { commitRename(original: name) }
                    .onExitCommand { renamingName = nil }
                    .onChange(of: renameFieldFocused) { _, focused in
                        // Commit on focus loss (click outside / tab away)
                        // — same validation path as Enter. The TextField
                        // only loses focus *after* `onSubmit` runs, and
                        // `commitRename` clears `renamingName` before
                        // returning, so this guard prevents a double-fire
                        // on a clean Enter. Escape still cancels via
                        // `.onExitCommand` (which nils `renamingName`
                        // before focus loss propagates here).
                        if !focused && renamingName == name {
                            commitRename(original: name)
                        }
                    }
            } else {
                Text(name)
                    .font(.omlxText(12, weight: .medium))
                    .foregroundStyle(isActive ? .white : theme.text)
            }
        }
        .padding(.horizontal, 11)
        .frame(height: 26)
        .background(
            Capsule().fill(
                isActive
                    ? metaColor
                    : (isPreviewed ? theme.selBg : theme.codeBg)
            )
        )
        .overlay(
            Capsule().strokeBorder(
                isActive ? Color.clear
                    : (isPreviewed ? theme.text
                        : (isBase ? metaColor.opacity(0.6) : theme.inputBorder)),
                style: StrokeStyle(
                    lineWidth: isPreviewed ? 1 : 0.5,
                    dash: (isBase && !isActive && !isPreviewed) ? [3, 2] : []
                )
            )
        )
        .contentShape(Capsule())
        .gesture(
            // ExclusiveGesture(first, second): the double-tap is tried
            // first; if it succeeds the single-tap doesn't fire. Without
            // this, double-clicking a chip would briefly flash the
            // preview before entering rename mode.
            ExclusiveGesture(
                TapGesture(count: 2).onEnded {
                    guard onRename != nil, !isEditing else { return }
                    startRename(name)
                },
                TapGesture(c|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<(?!<)",
end:">",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{
match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/],
className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={
keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]),
built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"],
literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{
begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{
begin:"\\b(0b[01']+)"},{
begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{
begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
}],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]
},r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/,
keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/,
end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/
},e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{
begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/,
contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]})
;s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],
o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{
illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]
},u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t]
},b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={
begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],
keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,
contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{
begin:"\x3c!--|--\x3e"},{begin:"</?",end:">"}]}]
}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",
end:"$",keywords:{
keyword:"if else elif endif define undef warning error line region endregion pragma checksum"
}},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/,
illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"
},t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",
relevance:0,end:/[{;=]/,illegal:/[^\s:]/,
contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{
beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/,
contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",
begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{
className:"string",begin:/"/,end:/"/}]},{
beginKeywords:"new return throw await else",relevance:0},{className:"function",
begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,
end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{
beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial",
relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,
contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params",
begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keyworll(full)
    for (int k = 0; k < tn * pack_factor; k++) {
      y[k] = static_cast<T>(result[k]);
    }
  }
}

template <
    typename T,
    const int group_size,
    const int bits,
    const bool aligned_N,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
METAL_FUNC void qmm_t_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    threadgroup T* Xs,
    threadgroup T* Ws,
    const constant int& K,
    const constant int& N,
    const constant int& M,
    const constant int& K_eff,
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  static_assert(BK >= SIMD_SIZE, "BK should be larger than SIMD_SIZE");
  static_assert(BK % SIMD_SIZE == 0, "BK should be divisible by SIMD_SIZE");

  (void)lid;

  constexpr int WM = 2;
  constexpr int WN = 2;
  constexpr int pack_factor = get_pack_factor<bits, 8>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();

  constexpr int BK_padded = (BK + 16 / sizeof(T));

  // Instantiate the appropriate BlockMMA and Loader
  using mma_t = mlx::steel::
      BlockMMA<T, T, BM, BN, BK, WM, WN, false, true, BK_padded, BK_padded>;
  using loader_x_t =
      mlx::steel::BlockLoader<T, BM, BK, BK_padded, 1, WM * WN * SIMD_SIZE>;
  using loader_w_t = QuantizedBlockLoader<
      T,
      BN,
      BK,
      BK_padded,
      1,
      WM * WN * SIMD_SIZE,
      group_size,
      bits>;

  // Set the block
  const int K_w = K * bytes_per_pack / pack_factor;
  const int K_g = K / group_size;
  const int y_row = tid.y * BM;
  const int y_col = tid.x * BN;

  auto wl = (const device uint8_t*)w;

  x += y_row * static_cast<int64_t>(K);
  wl += y_col * K_w;
  scales += y_col * K_g;
  biases += y_col * K_g;
  y += y_row * static_cast<int64_t>(N) + y_col;

  // Make the x loader and mma operation
  const short num_els = min(BM, M - y_row);
  const short num_outs = min(BN, N - y_col);
  loader_x_t loader_x(x, K, Xs, simd_gid, simd_lid);
  loader_w_t loader_w(wl, scales, biases, K, Ws, simd_gid, simd_lid);
  mma_t mma_op(simd_gid, simd_lid);

  if (num_els < BM) {
    if (!aligned_N && num_outs < BN) {
      for (int k = 0; k < K_eff; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_safe(short2(BK, num_els));
        loader_w.load_safe(short2(BK, num_outs));
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    } else {
      for (int k = 0; k < K_eff; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_safe(short2(BK, num_els));
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    }
  } else {
    if (!aligned_N && num_outs < BN) {
      for (int k = 0; k < K_eff; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_unsafe();
        loader_w.load_safe(short2(BK, num_outs));
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    } else {
      for (int k = 0; k < K_eff; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_unsafe();
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);

        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    }
  }

  // Store results to device memory
  threadgroup_barrier(mem_flags::mem_threadgroup);
  if (num_els < BM || num_outs < BN) {
    mma_op.store_result_safe(y, N, short2(num_outs, num_els));
  } else {
    mma_op.store_result(y, N);
  }
}

template <
    typename T,
    const int group_size,
    const int bits,
    const int BM = 32,
    const int BK = 32,
    const int BN = 32>
METAL_FUNC veateSubKeyRequest(BaseModel):
    """Request model for creating a sub API key."""

    key: str
    name: str = ""


class DeleteSubKeyRequest(BaseModel):
    """Request model for deleting a sub API key."""

    key: str


class CacheProbeRequest(BaseModel):
    """Request model for probing per-prompt cache state.

    Tokenizes a chat message list with the target model's tokenizer, then
    classifies each block's location in the cache hierarchy:
    - Hot SSD (in-RAM copy of SSD cache, ready to mount without disk read)
    - Disk SSD (persisted only, needs disk read to reuse)
    - Cold (fully uncached — would require full prefill)
    """

    model_id: str
    messages: list[dict[str, Any]]
    tools: list[dict[str, Any]] | None = None
    chat_template_kwargs: dict[str, Any] | None = None
    thinking_budget: int | None = None


class ModelSettingsRequest(BaseModel):
    """Request model for updating per-model settings."""

    model_alias: str | None = None
    model_type_override: str | None = None
    max_context_window: int | None = None
    max_tokens: int | None = None
    temperature: float | None = None
    top_p: float | None = None
    top_k: int | None = None
    repetition_penalty: float | None = None
    min_p: float | None = None
    presence_penalty: float | None = None
    force_sampling: bool | None = None
    max_tool_result_tokens: int | None = None
    chat_template_kwargs: dict[str, Any] | None = None
    forced_ct_kwargs: list[str] | None = None
    ttl_seconds: int | None = None
    index_cache_freq: int | None = None
    enable_thinking: bool | None = None
    thinking_budget_enabled: bool | None = None
    thinking_budget_tokens: int | None = None
    # TurboQuant KV cache (mlx-vlm backend)
    turboquant_kv_enabled: bool | None = None
    turboquant_kv_bits: float | None = None
    # SpecPrefill (experimental)
    specprefill_enabled: bool | None = None
    specprefill_draft_model: str | None = None
    specprefill_keep_pct: float | None = None
    specprefill_threshold: int | None = None
    # DFlash (block diffusion speculative decoding)
    dflash_enabled: bool | None = None
    dflash_draft_model: str | None = None
    dflash_draft_quant_enabled: bool | None = None
    dflash_draft_quant_weight_bits: int | None = None
    dflash_draft_quant_activation_bits: int | None = None
    dflash_draft_quant_group_size: int | None = None
    dflash_max_ctx: int | None = None
    dflash_in_memory_cache: bool | None = None
    dflash_in_memory_cache_max_entries: int | None = None
    dflash_in_memory_cache_max_bytes: int | None = None
    dflash_ssd_cache: bool | None = None
    dflash_ssd_cache_max_bytes: int | None = None
    dflash_draft_window_size: int | None = None
    dflash_draft_sink_size: int | None = None
    dflash_verify_mode: str | None = None
    # Native MTP (mlx-lm PR 990 / PR 15 monkey-patch)
    mtp_enabled: bool | None = None
    # VLM MTP speculative decoding via external assistant drafter (mlx-vlm 191d7c8+)
    vlm_mtp_enabled: bool | None = None
    vlm_mtp_draft_model: str | None = None
    vlm_mtp_draft_block_size: int | None = None
    reasoning_parser: str | None = None
    guided_grammar_enabled: bool | None = None
    guided_grammar: str | None = None
    is_pinned: bool | None = None
    is_default: bool | None = None
    is_hidden: bool | None = None
    is_favorite: bool | None = None
    # Security: per-model opt-in for trust_remote_code (issue #926)
    trust_remote_code: bool | None = None


class CreateProfileRequest(BaseModel):
    """Request body for creating a per-model profile."""

    name: str
    display_name: str
    api_name: str | None = None
    description: str | None = None
    settings: dict[str, Any] = Field(default_factory=dict)
    also_save_as_template: bool = False
    source_template: str | None = None
    expose_as_model: bool = False


class UpdateProfileRequest(BaseModel):
    """Request body for updating/renaming a per-model profile."""

    new_name: str | None = None
    display_name: str | None = None
    api_name: str | None = None
    ount: 1).onEnded {
                    guard !isEditing else { return }
                    onSelect(name)
                }
            )
        )
    }

    private func startRename(_ name: String) {
        renamingName = name
        renameText = name
        // Focus on the next runloop tick so the @FocusState observer sees
        // the TextField after it's been mounted into the hierarchy.
        DispatchQueue.main.async { renameFieldFocused = true }
    }

    private func commitRename(original: String) {
        let trimmed = renameText.trimmingCharacters(in: .whitespacesAndNewlines)
        // Always exit rename mode — validation failures silently revert
        // to the original name without an error banner.
        defer { renamingName = nil }
        guard !trimmed.isEmpty,
              trimmed != original,
              !names.contains(trimmed),
              Self.isValidSlug(trimmed)
        else { return }
        onRename?(original, trimmed)
    }

    /// Mirror of the server's profile-name slug rule
    /// (`omlx/model_profiles.py:validate_profile_name`). Pre-checking
    /// client-side avoids a doomed PUT round-trip for invalid names.
    private static func isValidSlug(_ s: String) -> Bool {
        guard let re = try? NSRegularExpression(
            pattern: #"^[a-z0-9][a-z0-9_-]{0,31}$"#
        ) else { return false }
        let range = NSRange(s.startIndex..., in: s)
        return re.firstMatch(in: s, range: range) != nil
    }
}

// MARK: - ActiveProfileBanner

/// Banner that sits above the chip groups (full) or above Basic/Advanced
/// (slim) summarizing what's currently attached + what unsaved work
/// exists. The state-machine logic lives in the VM; this view just
/// renders one of three shapes (working / named / defaults).
struct ActiveProfileBanner: View {
    let state: ActiveProfileState
    let isSlim: Bool

    /// nil when the corresponding action isn't relevant for this state.
    let onUpdateBasedOn: (() -> Void)?
    let onSaveAsNew: (() -> Void)?
    let onRevert: (() -> Void)?

    @Environment(\.omlxTheme) private var theme

    var body: some View {
        HStack(spacing: 12) {
            Circle()
                .fill(dotColor)
                .frame(width: 8, height: 8)
            VStack(alignment: .leading, spacing: 2) {
                Text(titleText)
                    .font(.omlxText(13.5, weight: .semibold))
                    .foregroundStyle(theme.text)
                subtitleView
            }
            Spacer(minLength: 8)
            actions
        }
        .padding(.horizontal, isSlim ? 12 : 14)
        .padding(.vertical, isSlim ? 10 : 12)
        .background(bannerBackground)
        .overlay(
            RoundedRectangle(cornerRadius: 12, style: .continuous)
                .strokeBorder(bannerBorder, lineWidth: 0.5)
        )
        .clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
        .padding(.horizontal, 14)
        .padding(.bottom, 12)
    }

    private var dotColor: Color {
        switch state {
        case .working:
            // Working / unsaved → amber (matches HTML mock and the
            // "you have unsaved edits" affordance pattern).
            return theme.amberDot
        case .named(let scope, _):
            return ProfileScopeMeta.color(scope, theme: theme)
        case .defaults:
            return theme.textTertiary
        }
    }

    private var titleText: String {
        switch state {
        case .working:                   return String(localized: "profile.banner.working.title",
                                                       defaultValue: "Working profile",
                                                       comment: "Profile banner title when the user has unsaved edits")
        case .named(_, let name):        return name
        case .defaults:                  return String(localized: "profile.banner.defaults.title",
                                                       defaultValue: "No profile",
                                                       comment: "Profile ds:n,relevance:0,
contains:[g,a,e.C_BLOCK_COMMENT_MODE]
},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{
const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{
name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{
keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"},
contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/
},t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0
},{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0
},t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{
begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}]
},t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{
begin:/:/,end:/[;}{]/,
contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{
begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri"
},contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0,
excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]",
relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/
},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{
$pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{
begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{
className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{
const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{
className:"meta",relevance:10,
match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/)
},{className:"comment",variants:[{
begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/),
end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{
className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,
end:/$/}]}},grmr_go:e=>{const n={
keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"],
type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"],
literal:["true","false","iota","nil"],
built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"]
};return{name:"Go",aliases:["golang"],keywords:n,illegal:"</",
contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string",
variants:[e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{begin:"`",end:"`"}]},{
className:"number",variants:[{begin:e.C_NUMBER_RE+"[i]",relevance:1
},e.C_NUMBER_MODE]},{begin:/:=/},{className:"function",beginKeywords:"func",
end:"\\s*(\\{|$)",excludeEnd:!0,contains:[e.TITLE_MODE,{className:"params",
begin:/\(/,end:/\)/,endsParent:!0,keywords:n,illegal:/["']/}]}]}},
grmr_graphql:e=>{const n=e.regex;return{name:"GraphQL",aliases:["gql"],
case_insensitive:!0,disableAutodetect:!1,keywords:{
keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"],
literal:["true","false","null"]},
contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{
scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation",
begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/,
end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{
scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)),
relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={
className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{
begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/,
end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{
begin:/\$\{(.*?)\}/}]},r={className:"literal",
begin:/\bon|off|true|false|yes|no\b/},s={clasoid qmm_n_impl(
    const device uint32_t* w,
    const device T* scales,
    const device T* biases,
    const device T* x,
    device T* y,
    threadgroup T* Xs,
    threadgroup T* Ws,
    const constant int& K,
    const constant int& N,
    const constant int& M,
    uint3 tid [[threadgroup_position_in_grid]],
    uint lid [[thread_index_in_threadgroup]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  static_assert(BK >= SIMD_SIZE, "BK should be larger than SIMD_SIZE");
  static_assert(BK % SIMD_SIZE == 0, "BK should be divisible by SIMD_SIZE");

  (void)lid;

  constexpr int WM = 2;
  constexpr int WN = 2;
  constexpr int pack_factor = get_pack_factor<bits, 8>();
  constexpr int bytes_per_pack = get_bytes_per_pack<bits>();

  constexpr int BK_padded = (BK + 16 / sizeof(T));
  constexpr int BN_padded = (BN + 16 / sizeof(T));

  // Instantiate the appropriate BlockMMA and Loader
  using mma_t = mlx::steel::
      BlockMMA<T, T, BM, BN, BK, WM, WN, false, false, BK_padded, BN_padded>;
  using loader_x_t = mlx::steel::
      BlockLoader<T, BM, BK, BK_padded, 1, WM * WN * SIMD_SIZE, 1, 4>;
  using loader_w_t = QuantizedBlockLoader<
      T,
      BK,
      BN,
      BN_padded,
      0,
      WM * WN * SIMD_SIZE,
      group_size,
      bits>;

  auto wl = (const device uint8_t*)w;

  // Set the block
  const int y_row = tid.y * BM;
  const int y_col = tid.x * BN;
  x += y_row * static_cast<int64_t>(K);
  wl += y_col * bytes_per_pack / pack_factor;
  scales += y_col / group_size;
  biases += y_col / group_size;
  y += y_row * static_cast<int64_t>(N) + y_col;

  // Make the x loader and mma operation
  const short num_els = min(BM, M - y_row);
  loader_x_t loader_x(x, K, Xs, simd_gid, simd_lid);
  loader_w_t loader_w(wl, scales, biases, N, Ws, simd_gid, simd_lid);
  mma_t mma_op(simd_gid, simd_lid);

  if (num_els < BM) {
    if ((K % BK) != 0) {
      const int k_blocks = K / BK;
      for (int k = 0; k < k_blocks; k++) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_safe(short2(BK, num_els));
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
      const short num_k = K - k_blocks * BK;
      threadgroup_barrier(mem_flags::mem_threadgroup);
      loader_x.load_safe(short2(num_k, num_els));
      loader_w.load_safe(short2(BN, num_k));
      threadgroup_barrier(mem_flags::mem_threadgroup);
      mma_op.mma(Xs, Ws);
    } else {
      for (int k = 0; k < K; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_safe(short2(BK, num_els));
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    }
  } else {
    if ((K % BK) != 0) {
      const int k_blocks = K / BK;
      for (int k = 0; k < k_blocks; k++) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_unsafe();
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
      const short num_k = K - k_blocks * BK;
      threadgroup_barrier(mem_flags::mem_threadgroup);
      loader_x.load_safe(short2(num_k, BM));
      loader_w.load_safe(short2(BN, num_k));
      threadgroup_barrier(mem_flags::mem_threadgroup);
      mma_op.mma(Xs, Ws);
    } else {
      for (int k = 0; k < K; k += BK) {
        threadgroup_barrier(mem_flags::mem_threadgroup);
        loader_x.load_unsafe();
        loader_w.load_unsafe();
        threadgroup_barrier(mem_flags::mem_threadgroup);
        mma_op.mma(Xs, Ws);
        loader_x.next();
        loader_w.next();
      }
    }
  }

  // Store results to device memory
  threadgroup_barrier(mem_flags::mem_threadgroup);
  if (num_els < BM) {
    mma_op.store_result_safe(y, N, short2(BN, num_els));
  } else {
    mma_op.store_result(y, N)description: str | None = None
    settings: dict[str, Any] | None = None
    source_template: str | None = None
    expose_as_model: bool | None = None
    also_save_as_template: bool = False


class CreateTemplateRequest(BaseModel):
    """Request body for creating a global template."""

    name: str
    display_name: str
    description: str | None = None
    settings: dict[str, Any] = Field(default_factory=dict)


class UpdateTemplateRequest(BaseModel):
    """Request body for updating/renaming a global template."""

    new_name: str | None = None
    display_name: str | None = None
    description: str | None = None
    settings: dict[str, Any] | None = None


class GlobalSettingsRequest(BaseModel):
    """Request model for updating global server settings."""

    # Server settings
    host: str | None = None
    port: int | None = None
    log_level: str | None = None
    server_aliases: list[str] | None = None
    sse_keepalive_mode: str | None = None
    auto_start_on_launch: bool | None = None
    burst_decode_mode: str | None = None  # "off" / "light" / "balanced" / "aggressive"
    preserve_mid_system_cache: bool | None = None

    # Model settings
    model_dirs: list[str] | None = None
    model_dir: str | None = None  # Deprecated: kept for backward compatibility
    model_fallback: bool | None = None
    hide_helper_models: bool | None = None

    # Memory enforcement
    memory_prefill_memory_guard: bool | None = None
    memory_guard_tier: str | None = (
        None  # "safe" / "balanced" / "aggressive" / "custom"
    )
    memory_guard_custom_ceiling_gb: float | None = (
        None  # only used when tier == "custom"
    )

    # Scheduler settings
    max_concurrent_requests: int | None = None
    embedding_batch_size: int | None = None
    chunked_prefill: bool | None = None
    prefill_priority: str | None = None  # "context" | "speed"

    # Cache settings
    cache_enabled: bool | None = None
    ssd_cache_dir: str | None = None
    ssd_cache_max_size: str | None = None
    hot_cache_only: bool | None = None
    hot_cache_max_size: str | None = None  # "0" = disabled, "8GB", etc.
    initial_cache_blocks: int | None = None  # Starting blocks (requires restart)

    # MCP settings
    mcp_config: str | None = None

    # HuggingFace settings
    hf_endpoint: str | None = None
    hf_cache_enabled: bool | None = None

    # ModelScope settings
    ms_endpoint: str | None = None

    # Network settings
    network_http_proxy: str | None = None
    network_https_proxy: str | None = None
    network_no_proxy: str | None = None
    network_ca_bundle: str | None = None

    # Sampling defaults
    sampling_max_context_window: int | None = None
    sampling_max_context_window_policy: int | None = Field(default=None, ge=1)
    sampling_max_tokens: int | None = None
    sampling_temperature: float | None = None
    sampling_top_p: float | None = None
    sampling_top_k: int | None = None
    sampling_repetition_penalty: float | None = None

    # Claude Code settings
    claude_code_mode: str | None = None
    claude_code_opus_model: str | None = None
    claude_code_sonnet_model: str | None = None
    claude_code_haiku_model: str | None = None

    # Other integrations settings
    integrations_copilot_model: str | None = None
    integrations_codex_model: str | None = None
    integrations_opencode_model: str | None = None
    integrations_openclaw_model: str | None = None
    integrations_hermes_model: str | None = None
    integrations_pi_model: str | None = None
    integrations_openclaw_tools_profile: (
        Literal["minimal", "coding", "messaging", "full"] | None
    ) = None
    markitdown_enabled: bool | None = None
    markitdown_expose_model: bool | None = None
    markitdown_max_file_size_mb: int | None = None
    markitdown_max_files_per_request: int | None = None
    markitdown_pdf_processing_engine: str | None = None

    # UI settings
    ui_language: str | None = None

    # Idle timeout settings. null disables the global fallback.
    idle_timeout_seconds: int | None = Field(default=banner title when the model uses server defaults")
        }
    }

    @ViewBuilder
    private var subtitleView: some View {
        switch state {
        case .working(let basedOn):
            if let basedOn {
                Text(String(localized: "profile.banner.working.subtitle.based_on",
                            defaultValue: "Unsaved · based on \(basedOn.name) (\(ProfileScopeMeta.label(basedOn.scope)))",
                            comment: "Profile banner subtitle for working state with a base profile; placeholders are profile name and scope label"))
                    .font(.omlxText(11.5))
                    .foregroundStyle(theme.textSecondary)
            } else {
                Text(String(localized: "profile.banner.working.subtitle.defaults",
                            defaultValue: "Unsaved · based on server defaults",
                            comment: "Profile banner subtitle when working profile has no named base"))
                    .font(.omlxText(11.5))
                    .foregroundStyle(theme.textSecondary)
            }
        case .named(let scope, _):
            Text(String(localized: "profile.banner.named.subtitle",
                        defaultValue: "\(ProfileScopeMeta.label(scope)) profile · active on this model",
                        comment: "Profile banner subtitle when a named profile is active; placeholder is scope label"))
                .font(.omlxText(11.5))
                .foregroundStyle(theme.textSecondary)
        case .defaults:
            Text(String(localized: "profile.banner.defaults.subtitle",
                        defaultValue: "Using server defaults · edit any field to start a working profile",
                        comment: "Profile banner subtitle when no profile is assigned"))
                .font(.omlxText(11.5))
                .foregroundStyle(theme.textSecondary)
        }
    }

    @ViewBuilder
    private var actions: some View {
        HStack(spacing: 6) {
            switch state {
            case .working(let basedOn):
                if let basedOn, basedOn.scope != .preset, let onUpdateBasedOn {
                    Button(String(localized: "profile.banner.action.update_based_on",
                                  defaultValue: "Update \(basedOn.name)",
                                  comment: "Profile banner action to overwrite the base profile with working edits; placeholder is the base profile's name")) { onUpdateBasedOn() }
                        .buttonStyle(.omlx(.normal, size: .small))
                }
                if let onSaveAsNew {
                    Button(String(localized: "profile.banner.action.save_as_new",
                                  defaultValue: "Save as new",
                                  comment: "Profile banner action that saves working edits as a new profile")) { onSaveAsNew() }
                        .buttonStyle(.omlx(.primary, size: .small))
                }
                if let onRevert {
                    Button(basedOn == nil
                           ? String(localized: "profile.banner.action.discard",
                                    defaultValue: "Discard",
                                    comment: "Profile banner action that discards working edits when there's no base profile")
                           : String(localized: "profile.banner.action.revert",
                                    defaultValue: "Revert",
                                    comment: "Profile banner action that reverts working edits back to the base profile")) { onRevert() }
                        .buttonStyle(.omlx(.plain, size: .small))
                }
            case .named, .defaults:
                EmptyView()
            }
        }
    }

    @ViewBuilder
    private var bannerBackground: some View {
        switch state {
        case .working:
            theme.amberDot.opacity(theme.isDark ? 0.08 : 0.07)
        case .named, .defaults:
            theme.groupBg
        }
    }

    private var bannerBorder: Color {
        switch state {
        case .working:           returnsName:"string",
contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{
begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]
},o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0
},l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{
name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/,
contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{
begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)),
className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{
const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={
keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"],
literal:["false","true","null"],
type:["char","boolean","long","float","int","byte","short","double"],
built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{
begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/,
end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0}
;return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/,
contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,
relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{
begin:/import java\.[a-z]+\./,keywords:"import",relevance:2
},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/,
className:"string",contains:[e.BACKSLASH_ESCAPE]
},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{
match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{
1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{
begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type",
3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword",
3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{
beginKeywords:"new throw return else",relevance:0},{
begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{
2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/,
end:/\)/,keywords:i,relevance:0,
contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE]
},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe,
grmr_json:e=>{const n=["true","false","null"],t={scope:"literal",
beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{
className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{
match:/[{}[\],:]/,className:"punctuation",relevance:0
},e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],
illegal:"\\S"}},grmr_kotlin:e=>{const n={
keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual",
built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",
literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"
},a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={
className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string",
variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'",
illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,
contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={
className:"meta",
begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"
},o={className:";
  }
}

template <typename T>
METAL_FUNC void adjust_matrix_offsets(
    const device T*& x,
    const device uint32_t*& w,
    const device T*& scales,
    const device T*& biases,
    device T*& y,
    int output_stride,
    const constant int& x_batch_ndims,
    const constant int* x_shape,
    const constant int64_t* x_strides,
    const constant int& w_batch_ndims,
    const constant int* w_shape,
    const constant int64_t* w_strides,
    const constant int64_t* s_strides,
    const constant int64_t* b_strides,
    uint3 tid [[threadgroup_position_in_grid]]) {
  // Set the input/output matrices
  uint32_t x_idx = tid.z;
  uint32_t w_idx = tid.z;
  if (x_batch_ndims == 1) {
    x += x_idx * x_strides[0];
  } else {
    x += elem_to_loc(x_idx, x_shape, x_strides, x_batch_ndims);
  }
  if (w_batch_ndims == 1) {
    w += w_idx * w_strides[0];
    scales += w_idx * s_strides[0];
    biases += w_idx * b_strides[0];
  } else {
    ulong3 idx = elem_to_loc_broadcast(
        w_idx, w_shape, w_strides, s_strides, b_strides, w_batch_ndims);
    w += idx.x;
    scales += idx.y;
    biases += idx.z;
  }
  y += tid.z * output_stride;
}

template <typename T>
METAL_FUNC void adjust_matrix_offsets(
    const device T*& x,
    const device uint32_t*& w,
    const device T*& scales,
    const device T*& biases,
    const device uint32_t* lhs_indices,
    const device uint32_t* rhs_indices,
    device T*& y,
    int output_stride,
    const constant int& batch_ndims,
    const constant int* batch_shape,
    const constant int64_t* lhs_strides,
    const constant int64_t* rhs_strides,
    const constant int& x_batch_ndims,
    const constant int* x_shape,
    const constant int64_t* x_strides,
    const constant int& w_batch_ndims,
    const constant int* w_shape,
    const constant int64_t* w_strides,
    const constant int64_t* s_strides,
    const constant int64_t* b_strides,
    uint3 tid [[threadgroup_position_in_grid]]) {
  // Set the input/output matrices
  uint32_t x_idx;
  uint32_t w_idx;
  if (batch_ndims == 1) {
    x_idx = lhs_indices[tid.z * lhs_strides[0]];
    w_idx = rhs_indices[tid.z * rhs_strides[0]];
  } else {
    ulong2 idx = elem_to_loc_broadcast(
        tid.z, batch_shape, lhs_strides, rhs_strides, batch_ndims);
    x_idx = lhs_indices[idx.x];
    w_idx = rhs_indices[idx.y];
  }
  if (x_batch_ndims == 1) {
    x += x_idx * x_strides[0];
  } else {
    x += elem_to_loc(x_idx, x_shape, x_strides, x_batch_ndims);
  }
  if (w_batch_ndims == 1) {
    w += w_idx * w_strides[0];
    scales += w_idx * s_strides[0];
    biases += w_idx * b_strides[0];
  } else {
    ulong3 idx = elem_to_loc_broadcast(
        w_idx, w_shape, w_strides, s_strides, b_strides, w_batch_ndims);
    w += idx.x;
    scales += idx.y;
    biases += idx.z;
  }
  y += tid.z * output_stride;
}

template <typename T, int group_size, int bits, int D, bool batched>
[[kernel]] void affine_qmv_quad(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint quad_gid [[quadgroup_index_in_threadgroup]],
    uint quad_lid [[thread_index_in_quadgroup]]) {
  if (batched) {
    int M = x_shape[x_batch_ndims];
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        out_vec_size * M,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strNone, ge=60)

    # Auth settings
    api_key: str | None = None
    skip_api_key_verification: bool | None = None


class HFDownloadRequest(BaseModel):
    """Request model for starting a HuggingFace model download."""

    repo_id: str
    hf_token: str = ""


class HFRetryRequest(BaseModel):
    """Request model for retrying a HuggingFace model download."""

    hf_token: str = ""


class MSDownloadRequest(BaseModel):
    """Request model for starting a ModelScope model download."""

    model_id: str
    ms_token: str = ""


class MSRetryRequest(BaseModel):
    """Request model for retrying a ModelScope model download."""

    ms_token: str = ""


class OQStartRequest(BaseModel):
    """Request model for starting an oQ quantization task."""

    model_path: str
    oq_level: float
    group_size: int = 64
    sensitivity_model_path: str = ""
    text_only: bool = False
    dtype: str = "bfloat16"
    preserve_mtp: bool = False
    auto_proxy_sensitivity: bool = True
    enhanced: bool = False
    imatrix_cache_path: str = ""
    imatrix_reuse_cache: bool = True
    imatrix_strict: bool = False
    imatrix_num_samples: int = 128
    imatrix_seq_length: int = 512
    mtp_assistant_model_path: str = ""


class HFUploadRequest(BaseModel):
    """Request model for starting a HuggingFace upload task."""

    model_path: str
    repo_id: str
    hf_token: str
    readme_source_path: str = ""
    auto_readme: bool = True
    redownload_notice: bool = False
    private: bool = False


class HFValidateTokenRequest(BaseModel):
    """Request model for validating a HuggingFace token."""

    hf_token: str


# =============================================================================
# Runtime Settings Application Functions
# =============================================================================


def _format_cache_size(size_bytes: int) -> str:
    """Format cache size in bytes to human-readable string (e.g., '100GB')."""
    gb = size_bytes / (1024**3)
    if gb >= 1:
        return f"{gb:.0f}GB"
    mb = size_bytes / (1024**2)
    return f"{mb:.0f}MB"


def _parse_hot_cache_max_size(value: str) -> int:
    """Parse hot cache max size. Hot cache does not support an auto sentinel."""
    from ..config import parse_size

    normalized = value.strip()
    if normalized.lower() == "auto":
        raise ValueError(
            "Invalid hot_cache_max_size: 'auto' is not supported; "
            "use '0' to disable or a size like '8GB'"
        )

    try:
        size = parse_size(normalized)
    except ValueError as exc:
        raise ValueError(f"Invalid hot_cache_max_size: {exc}") from exc

    if size < 0:
        raise ValueError(
            "Invalid hot_cache_max_size: must be '0' to disable "
            "or a non-negative size"
        )
    return size


_PAROQUANT_REASON = "Not supported on paroquant models yet (compatibility not verified)"


def _paroquant_compat_for_model(model_info: dict) -> tuple[bool, str]:
    """Detect whether a model is paroquant-quantized.

    Returns ``(is_paroquant, reason)``. ``is_paroquant`` is True iff
    ``config.json`` declares ``quantization_config.quant_method == "paroquant"``.
    Reason is the user-facing string surfaced as a tooltip/banner on the
    admin model settings modal when paroquant gates an experimental toggle.
    """
    import json
    from pathlib import Path

    model_path = model_info.get("model_path") or ""
    if not model_path:
        return False, ""
    cfg_path = Path(model_path) / "config.json"
    if not cfg_path.exists():
        return False, ""
    try:
        cfg = json.loads(cfg_path.read_text())
    except Exception:
        return False, ""
    qcfg = cfg.get("quantization_config") or {}
    method = (qcfg.get("quant_method") or "").lower()
    if method == "paroquant":
        return True, _PAROQUANT_REASON
    return False, ""


def _dflash_compat_for_model(model_info: dict) -> tuple[bool, str]:
    """Resolve dflash compatibility for an engine_pool model dict.

    Returns ``(False, "")`` when dflash-mlx is not installed so the UI hides
 theme.amberDot.opacity(theme.isDark ? 0.28 : 0.35)
        case .named, .defaults:  return theme.groupBorder
        }
    }
}

// MARK: - SaveAsPopover

struct SaveAsPopover: View {
    @Binding var name: String
    @Binding var scope: ProfileScope
    /// Save as new only supports global / model; preset is read-only.
    let onCommit: () -> Void
    let onCancel: () -> Void

    @Environment(\.omlxTheme) private var theme
    @FocusState private var nameFocused: Bool

    var body: some View {
        HStack(spacing: 10) {
            Text(String(localized: "profile.save_as.title",
                        defaultValue: "Save current profile as",
                        comment: "Lead label inside the Save-as popover for naming a new profile"))
                .font(.omlxText(12, weight: .medium))
                .foregroundStyle(theme.textSecondary)
            Segmented(
                selection: $scope,
                options: [
                    (.global, String(localized: "profile.scope.global",
                                     defaultValue: "Global",
                                     comment: "Scope label for user-defined global profiles")),
                    (.model,  String(localized: "profile.scope.model",
                                     defaultValue: "Model",
                                     comment: "Scope label for per-model profiles")),
                ]
            )
            TextInput(text: $name,
                      placeholder: String(localized: "profile.save_as.name.placeholder",
                                          defaultValue: "profile-name",
                                          comment: "Placeholder text inside the new-profile name field"),
                      mono: true)
                .frame(maxWidth: .infinity)
                .focused($nameFocused)
                .onSubmit { onCommit() }
            Button(String(localized: "common.cancel",
                          defaultValue: "Cancel",
                          comment: "Generic Cancel button label")) { onCancel() }
                .buttonStyle(.omlx(.normal, size: .small))
            Button(String(localized: "common.save",
                          defaultValue: "Save",
                          comment: "Generic Save button label")) { onCommit() }
                .buttonStyle(.omlx(.primary, size: .small))
                .disabled(name.trimmingCharacters(in: .whitespaces).isEmpty)
        }
        .padding(12)
        .background(theme.groupBg)
        .overlay(
            RoundedRectangle(cornerRadius: 12, style: .continuous)
                .strokeBorder(theme.groupBorder, lineWidth: 0.5)
        )
        .clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
        .padding(.horizontal, 14)
        .padding(.bottom, 12)
        .onAppear { nameFocused = true }
    }
}

// MARK: - ProfileDetailCard

/// Compact visual summary of a profile's settings — sampling meters,
/// capacity stats, penalty bars, behavior flag chips, and aliases.
/// Renders below the chip groups (preview-on-click) and at the bottom
/// of the Profiles tab as the read-only Server Defaults card.
struct ProfileDetailCard: View {
    let name: String
    let scope: ProfileScope?  // nil → defaults card (no scope dot)
    let settings: [String: AnyCodable]
    let isActive: Bool
    let isWorking: Bool
    let basedOn: ActiveProfileState.NamedProfileRef?
    /// True when the card is being shown for the chip the working
    /// profile forked from — dashed border treatment in the chip group,
    /// "Base of working" badge here.
    let isWorkingBase: Bool
    /// Compact mode shrinks padding; used for the Server Defaults card.
    let compact: Bool
    let hasWorking: Bool

    // nil means the action isn't relevant for this card.
    var onApply: (() -> Void)? = nil
    var onUpdateFromWorking: (() -> Void)? = nil
    var onDelete: (() -> Void)? = nil
    var onClosePreview: (() -> Void)? = nil
    /// Server `expose_as_model` state for this profile. Only meaningful
    /// when `onToggleExpose` is wired (mometa",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,
end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}]
},l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={
variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,
contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g],
{name:"Kotlin",aliases:["kt","kts"],keywords:n,
contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",
begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",
begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",
begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$",
returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{
begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,
contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin:/</,end:/>/,
keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,
endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,
endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0
},e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{
begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{
3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,
illegal:"extends implements",contains:[{
beginKeywords:"public protected internal private constructor"
},e.UNDERSCORE_TITLE_MODE,{className:"type",begin:/</,end:/>/,excludeBegin:!0,
excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/,
excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env",
end:"$",illegal:"\n"},l]}},grmr_less:e=>{
const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({
className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n,
relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only",
attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c,
relevance:0}
;s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{
begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",
excludeEnd:!0}
},n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{
className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0
},n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({
begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0,
contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:",
returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/
},n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b",
end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}]
},m={className:"keyword",
begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",
starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={
className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a
}],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{
begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0,
returnEnd:!0,illegal:"[<='$\"]",relevance:0,
contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{
begin:"\\b("+re.join("|")+")\\b",className:"selector-tag"
},n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{
className:"selector-pseudo",begin:":("+oe.join("|")+")"},{
className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/,
end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={
begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]}
;return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH),
{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}},
grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={beides,
        b_strides,
        tid);
  }
  qmv_quad_impl<T, group_size, bits, D>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      quad_gid,
      quad_lid);
}

template <typename T, int group_size, int bits, bool batched>
[[kernel]] void affine_qmv_fast(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  if (batched) {
    int M = x_shape[x_batch_ndims];
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        out_vec_size * M,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }
  qmv_fast_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      simd_gid,
      simd_lid);
}

template <typename T, const int group_size, const int bits, bool batched>
[[kernel]] void affine_qmv(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[simdgroup_index_in_threadgroup]],
    uint simd_lid [[thread_index_in_simdgroup]]) {
  if (batched) {
    int M = x_shape[x_batch_ndims];
    adjust_matrix_offsets<T>(
        x,
        w,
        scales,
        biases,
        y,
        out_vec_size * M,
        x_batch_ndims,
        x_shape,
        x_strides,
        w_batch_ndims,
        w_shape,
        w_strides,
        s_strides,
        b_strides,
        tid);
  }
  qmv_impl<T, group_size, bits>(
      w,
      scales,
      biases,
      x,
      y,
      in_vec_size,
      out_vec_size,
      tid,
      simd_gid,
      simd_lid);
}

template <typename T, const int group_size, const int bits, bool batched>
[[kernel]] void affine_qvm(
    const device uint32_t* w [[buffer(0)]],
    const device T* scales [[buffer(1)]],
    const device T* biases [[buffer(2)]],
    const device T* x [[buffer(3)]],
    device T* y [[buffer(4)]],
    const constant int& in_vec_size [[buffer(5)]],
    const constant int& out_vec_size [[buffer(6)]],
    const constant int& x_batch_ndims [[buffer(7)]],
    const constant int* x_shape [[buffer(8)]],
    const constant int64_t* x_strides [[buffer(9)]],
    const constant int& w_batch_ndims [[buffer(10)]],
    const constant int* w_shape [[buffer(11)]],
    const constant int64_t* w_strides [[buffer(12)]],
    const constant int64_t* s_strides [[buffer(13)]],
    const constant int64_t* b_strides [[buffer(14)]],
    uint3 tid [[threadgroup_position_in_grid]],
    uint simd_gid [[s    the compat hint instead of pointing the user at an unrelated reason.
    """
    is_paro, paro_reason = _paroquant_compat_for_model(model_info)
    if is_paro:
        return False, paro_reason
    try:
        from ..engine.dflash import is_dflash_compatible
    except ImportError:
        return False, ""
    model_path = model_info.get("model_path") or ""
    if not model_path:
        return False, "model_path missing"
    return is_dflash_compatible(model_path)


def _entry_is_diffusion_model(entry) -> bool:
    model_type = (getattr(entry, "config_model_type", None) or "").lower()
    return model_type.replace("-", "_") == "diffusion_gemma"


def _sanitize_diffusion_settings_dict(settings: dict) -> None:
    """Clear unsupported diffusion-lane settings before ModelSettings parsing.

    Tool-calling settings (``max_tool_result_tokens``) are intentionally NOT
    cleared: tool calling is prompt-driven plus output parsing and works on
    the diffusion lane when a tool parser matches the chat template.
    """
    unsupported_none_fields = (
        "top_p",
        "top_k",
        "min_p",
        "repetition_penalty",
        "presence_penalty",
        "enable_thinking",
        "preserve_thinking",
        "thinking_budget_tokens",
        "reasoning_parser",
        "guided_grammar",
        "index_cache_freq",
        "specprefill_draft_model",
        "specprefill_keep_pct",
        "specprefill_threshold",
        "dflash_draft_model",
        "dflash_draft_quant_enabled",
        "dflash_draft_quant_weight_bits",
        "dflash_draft_quant_activation_bits",
        "dflash_draft_quant_group_size",
        "dflash_max_ctx",
        "dflash_draft_window_size",
        "dflash_draft_sink_size",
        "dflash_verify_mode",
        "vlm_mtp_draft_model",
        "vlm_mtp_draft_block_size",
    )
    for key in unsupported_none_fields:
        settings[key] = None

    settings["force_sampling"] = False
    settings["thinking_budget_enabled"] = False
    settings["guided_grammar_enabled"] = False
    settings["turboquant_kv_enabled"] = False
    settings["turboquant_kv_bits"] = 4
    settings["turboquant_skip_last"] = True
    settings["specprefill_enabled"] = False
    settings["dflash_enabled"] = False
    settings["dflash_in_memory_cache"] = True
    settings["dflash_in_memory_cache_max_entries"] = 4
    settings["dflash_in_memory_cache_max_bytes"] = 8 * 1024 * 1024 * 1024
    settings["dflash_ssd_cache"] = False
    settings["dflash_ssd_cache_max_bytes"] = 20 * 1024 * 1024 * 1024
    settings["mtp_enabled"] = False
    settings["vlm_mtp_enabled"] = False

    unsupported_ct_kwargs = {
        "enable_thinking",
        "reasoning_effort",
        "preserve_thinking",
    }
    kwargs = settings.get("chat_template_kwargs")
    if kwargs:
        filtered_kwargs = {
            k: v for k, v in kwargs.items() if k not in unsupported_ct_kwargs
        }
        settings["chat_template_kwargs"] = filtered_kwargs or None
    forced = settings.get("forced_ct_kwargs")
    if forced:
        allowed = set(settings.get("chat_template_kwargs") or {})
        filtered_forced = [
            k for k in forced if k not in unsupported_ct_kwargs and k in allowed
        ]
        settings["forced_ct_kwargs"] = filtered_forced or None


def _sanitize_diffusion_model_settings(settings) -> None:
    """Clear settings that the serial diffusion lane does not implement.

    ``max_tool_result_tokens`` is intentionally preserved — tool calling
    works on the diffusion lane (prompt-driven + output parsing).
    """
    settings.top_p = None
    settings.top_k = None
    settings.min_p = None
    settings.repetition_penalty = None
    settings.presence_penalty = None
    settings.force_sampling = False
    settings.enable_thinking = None
    settings.preserve_thinking = None
    settings.thinking_budget_enabled = False
    settings.thinking_budget_tokens = None
    settings.reasoning_parser = None
    settings.guided_grammar_enabled = False
    settings.guided_grammar = None

    unsupported_ct_kwargs = {
        "enable_thdel-scope profiles).
    var exposeAsModel: Bool = false
    /// Derived API model ID (`<base-model>:<profile-name>`) shown next to
    /// the toggle while exposure is on.
    var exposedModelId: String? = nil
    /// Server-derived `has_engine_fields` — true when the profile carries
    /// engine-construction overrides, which the exposed-model overlay
    /// ignores. Shows a warning under the toggle while exposure is on.
    var hasEngineFields: Bool = false
    /// Non-nil renders the "Expose as model" toggle; the callback receives
    /// the requested state. Pass nil for templates, presets, and the
    /// defaults card.
    var onToggleExpose: ((Bool) -> Void)? = nil

    @Environment(\.omlxTheme) private var theme

    private var scopeColor: Color {
        guard let scope else { return theme.textTertiary }
        return ProfileScopeMeta.color(scope, theme: theme)
    }

    private var showApply: Bool { onApply != nil && !isActive }
    private var showUpdate: Bool { onUpdateFromWorking != nil && hasWorking }
    private var showDelete: Bool {
        onDelete != nil && scope != .preset && scope != nil
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 14) {
            header
            exposeRow
            sections
        }
        .padding(compact ? 12 : 14)
        .background(theme.groupBg)
        .overlay(
            RoundedRectangle(cornerRadius: 14, style: .continuous)
                .strokeBorder(theme.groupBorder, lineWidth: 0.5)
        )
        .clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
        .padding(.horizontal, 14)
        .padding(.bottom, 14)
    }

    @ViewBuilder
    private var header: some View {
        HStack(spacing: 12) {
            iconBox
            VStack(alignment: .leading, spacing: 4) {
                HStack(spacing: 8) {
                    Text(name)
                        .font(.omlxText(16, weight: .semibold))
                        .foregroundStyle(theme.text)
                    if isActive && !isWorking {
                        badge(text: String(localized: "profile.detail.badge.active",
                                           defaultValue: "ACTIVE",
                                           comment: "Badge shown on the profile detail card when this profile is active on the model"),
                              fg: .white, bg: theme.greenDot)
                    }
                    if isWorking {
                        badge(text: String(localized: "profile.detail.badge.unsaved",
                                           defaultValue: "UNSAVED",
                                           comment: "Badge on the profile detail card indicating unsaved working-state edits"),
                              fg: Color(rgb24: 0x1A1407), bg: theme.amberDot)
                    }
                    if isWorkingBase && !isWorking {
                        badge(text: String(localized: "profile.detail.badge.base_of_working",
                                           defaultValue: "BASE OF WORKING",
                                           comment: "Badge on the profile detail card marking the profile the working profile forked from"),
                              fg: theme.textSecondary, bg: .clear,
                              border: theme.inputBorder)
                    }
                }
                HStack(spacing: 6) {
                    Circle()
                        .fill(isWorking ? theme.amberDot : scopeColor)
                        .frame(width: 6, height: 6)
                    Text(subtitleText)
                        .font(.omlxText(11))
                        .foregroundStyle(theme.textSecondary)
                }
            }
            Spacer(minLength: 8)
            HStack(spacing: 6) {
                if let onClosePreview {
                    Button(String(localized: "profile.detail.action.done",
                                  defaultValue: "Done",
                                  comment: "Profile detail card button that closes the preview overlay")) { onClosePrevigin:n,end:t,contains:["self"]
},i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10
})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,
literal:"true false nil",
keyword:"and break do else elseif end for goto if in local not or repeat return then until while",
built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"
},contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)",
contains:[e.inherit(e.TITLE_MODE,{
begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",
begin:"\\(",endsWithParent:!0,contains:i}].concat(i)
},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",
begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={
className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)",
contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%<?\^\+\*]/}]},t={className:"string",
begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n]},a={className:"variable",
begin:/\$\([\w-]+\s/,end:/\)/,keywords:{
built_in:"subst patsubst strip findstring filter filter-out sort word wordlist firstword lastword dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath error warning shell origin flavor foreach if or and call eval file value"
},contains:[n]},i={begin:"^"+e.UNDERSCORE_IDENT_RE+"\\s*(?=[:+?]?=)"},r={
className:"section",begin:/^[^\s]+:/,end:/$/,contains:[n]};return{
name:"Makefile",aliases:["mk","mak","make"],keywords:{$pattern:/[\w-]+/,
keyword:"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath"
},contains:[e.HASH_COMMENT_MODE,n,t,a,i,{className:"meta",begin:/^\.PHONY:/,
end:/$/,keywords:{$pattern:/[\.\w]+/,keyword:".PHONY"}},r]}},grmr_markdown:e=>{
const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={
variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{
begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,
relevance:2},{
begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/),
relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{
begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/
},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,
returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",
excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",
end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[],
variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}]
},i={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{
begin:/_(?![_\s])/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[]
}),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r)
;let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o)
})),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{
className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{
begin:"(?=^
