From 7d3b4e5ea3bb893e726e2a89c9726dc7e79b893d Mon Sep 17 00:00:00 2001 From: Jon Saad-Falcon <41205309+jonsaadfalcon@users.noreply.github.com> Date: Tue, 24 Mar 2026 18:04:25 -0700 Subject: [PATCH] fix: add MLX engine support to Qwen3.5 model catalog entries Fixes recommend_model() returning empty string on Apple Silicon when MLX is the recommended engine. Also adds gguf_file and mlx_repo download metadata, and estimated_download_gb helper. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/openjarvis/core/config.py | 5 +++ src/openjarvis/intelligence/model_catalog.py | 16 ++++++-- tests/core/test_recommend_model.py | 40 ++++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/openjarvis/core/config.py b/src/openjarvis/core/config.py index 5ca8fa77..33160232 100644 --- a/src/openjarvis/core/config.py +++ b/src/openjarvis/core/config.py @@ -248,6 +248,11 @@ def recommend_model(hw: HardwareInfo, engine: str) -> str: return "" +def estimated_download_gb(parameter_count_b: float) -> float: + """Estimate download size in GB for Q4_K_M quantized model.""" + return parameter_count_b * 0.5 * 1.1 + + # --------------------------------------------------------------------------- # Configuration hierarchy # --------------------------------------------------------------------------- diff --git a/src/openjarvis/intelligence/model_catalog.py b/src/openjarvis/intelligence/model_catalog.py index d77c1740..ee36976f 100644 --- a/src/openjarvis/intelligence/model_catalog.py +++ b/src/openjarvis/intelligence/model_catalog.py @@ -45,11 +45,13 @@ BUILTIN_MODELS: List[ModelSpec] = [ parameter_count_b=3.0, active_parameter_count_b=0.6, context_length=131072, - supported_engines=("ollama", "vllm", "llamacpp", "sglang"), + supported_engines=("ollama", "vllm", "llamacpp", "sglang", "mlx"), provider="alibaba", metadata={ "architecture": "moe", "hf_repo": "Qwen/Qwen3.5-3B", + "gguf_file": "qwen3.5-3b-q4_k_m.gguf", + "mlx_repo": "mlx-community/Qwen3.5-3B-4bit", }, ), ModelSpec( @@ -58,11 +60,13 @@ BUILTIN_MODELS: List[ModelSpec] = [ parameter_count_b=8.0, active_parameter_count_b=1.0, context_length=131072, - supported_engines=("ollama", "vllm", "llamacpp", "sglang"), + supported_engines=("ollama", "vllm", "llamacpp", "sglang", "mlx"), provider="alibaba", metadata={ "architecture": "moe", "hf_repo": "Qwen/Qwen3.5-8B", + "gguf_file": "qwen3.5-8b-q4_k_m.gguf", + "mlx_repo": "mlx-community/Qwen3.5-8B-4bit", }, ), ModelSpec( @@ -71,11 +75,13 @@ BUILTIN_MODELS: List[ModelSpec] = [ parameter_count_b=14.0, active_parameter_count_b=2.0, context_length=131072, - supported_engines=("ollama", "vllm", "llamacpp", "sglang"), + supported_engines=("ollama", "vllm", "llamacpp", "sglang", "mlx"), provider="alibaba", metadata={ "architecture": "moe", "hf_repo": "Qwen/Qwen3.5-14B", + "gguf_file": "qwen3.5-14b-q4_k_m.gguf", + "mlx_repo": "mlx-community/Qwen3.5-14B-4bit", }, ), ModelSpec( @@ -223,11 +229,13 @@ BUILTIN_MODELS: List[ModelSpec] = [ active_parameter_count_b=0.5, context_length=262144, min_vram_gb=3.0, - supported_engines=("ollama", "vllm", "sglang", "llamacpp"), + supported_engines=("ollama", "vllm", "sglang", "llamacpp", "mlx"), provider="alibaba", metadata={ "architecture": "moe", "hf_repo": "Qwen/Qwen3.5-4B", + "gguf_file": "qwen3.5-4b-q4_k_m.gguf", + "mlx_repo": "mlx-community/Qwen3.5-4B-4bit", }, ), ModelSpec( diff --git a/tests/core/test_recommend_model.py b/tests/core/test_recommend_model.py index 8f03d430..61600b69 100644 --- a/tests/core/test_recommend_model.py +++ b/tests/core/test_recommend_model.py @@ -115,3 +115,43 @@ class TestRecommendModelEdgeCases: # With ollama, 397b is excluded (only vllm, sglang) result = recommend_model(hw, "ollama") assert result == "qwen3.5:122b" + + +class TestRecommendModelMlx: + """Apple Silicon (MLX) model recommendation.""" + + def test_apple_silicon_8gb_mlx(self) -> None: + hw = HardwareInfo( + platform="darwin", + ram_gb=8.0, + gpu=GpuInfo(vendor="apple", name="Apple M1", vram_gb=8.0, count=1), + ) + result = recommend_model(hw, "mlx") + assert result == "qwen3.5:8b" + + def test_apple_silicon_16gb_mlx(self) -> None: + hw = HardwareInfo( + platform="darwin", + ram_gb=16.0, + gpu=GpuInfo(vendor="apple", name="Apple M2", vram_gb=16.0, count=1), + ) + result = recommend_model(hw, "mlx") + assert result == "qwen3.5:14b" + + def test_apple_silicon_32gb_mlx(self) -> None: + hw = HardwareInfo( + platform="darwin", + ram_gb=32.0, + gpu=GpuInfo(vendor="apple", name="Apple M2 Pro", vram_gb=32.0, count=1), + ) + result = recommend_model(hw, "mlx") + assert result == "qwen3.5:14b" + + def test_apple_silicon_64gb_mlx(self) -> None: + hw = HardwareInfo( + platform="darwin", + ram_gb=64.0, + gpu=GpuInfo(vendor="apple", name="Apple M2 Max", vram_gb=64.0, count=1), + ) + result = recommend_model(hw, "mlx") + assert result == "qwen3.5:14b"