mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-28 13:26:48 +00:00
The model catalog listed non-existent Qwen3.5 sizes (3B, 8B, 14B) and pointed to MLX community repos that don't exist, causing `jarvis init` to recommend models that cannot be downloaded on Apple Silicon. Replace with the actual Qwen3.5 model family sizes (0.8B, 2B, 9B, 27B) and verified mlx-community repo URLs from HuggingFace. Fixes #129 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
110 lines
3.7 KiB
Python
110 lines
3.7 KiB
Python
"""Tests for ``jarvis model pull`` multi-engine support."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest import mock
|
|
|
|
from click.testing import CliRunner
|
|
from rich.console import Console
|
|
|
|
from openjarvis.cli.model import ollama_pull
|
|
|
|
|
|
class TestOllamaPull:
|
|
"""Test the extracted ollama_pull helper."""
|
|
|
|
def test_ollama_pull_success(self) -> None:
|
|
import io
|
|
|
|
console = Console(file=io.StringIO())
|
|
mock_lines = [
|
|
'{"status": "pulling manifest"}',
|
|
'{"status": "downloading", "total": 100, "completed": 100}',
|
|
'{"status": "success"}',
|
|
]
|
|
mock_resp = mock.MagicMock()
|
|
mock_resp.raise_for_status = mock.MagicMock()
|
|
mock_resp.iter_lines.return_value = iter(mock_lines)
|
|
mock_resp.__enter__ = mock.MagicMock(return_value=mock_resp)
|
|
mock_resp.__exit__ = mock.MagicMock(return_value=False)
|
|
|
|
with mock.patch("httpx.stream", return_value=mock_resp):
|
|
result = ollama_pull("http://localhost:11434", "qwen3.5:2b", console)
|
|
assert result is True
|
|
|
|
def test_ollama_pull_connect_error(self) -> None:
|
|
import io
|
|
|
|
import httpx
|
|
|
|
console = Console(file=io.StringIO())
|
|
with mock.patch("httpx.stream", side_effect=httpx.ConnectError("refused")):
|
|
result = ollama_pull("http://localhost:11434", "qwen3.5:2b", console)
|
|
assert result is False
|
|
|
|
|
|
class TestPullCliMultiEngine:
|
|
"""Test the pull CLI command dispatches to correct engine."""
|
|
|
|
def test_pull_llamacpp_uses_huggingface_cli(self) -> None:
|
|
from openjarvis.cli import cli
|
|
|
|
runner = CliRunner()
|
|
with (
|
|
mock.patch("openjarvis.cli.model.load_config") as mock_cfg,
|
|
mock.patch("subprocess.run") as mock_run,
|
|
):
|
|
mock_cfg.return_value.engine.default = "llamacpp"
|
|
mock_cfg.return_value.engine.ollama_host = None
|
|
mock_run.return_value = mock.MagicMock(returncode=0)
|
|
|
|
result = runner.invoke(
|
|
cli, ["model", "pull", "qwen3.5:9b", "--engine", "llamacpp"]
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
mock_run.assert_called_once()
|
|
call_args = mock_run.call_args[0][0]
|
|
assert "huggingface-cli" in call_args
|
|
assert "qwen3.5-9b-q4_k_m.gguf" in call_args
|
|
|
|
def test_pull_mlx_uses_huggingface_cli(self) -> None:
|
|
from openjarvis.cli import cli
|
|
|
|
runner = CliRunner()
|
|
with (
|
|
mock.patch("openjarvis.cli.model.load_config") as mock_cfg,
|
|
mock.patch("subprocess.run") as mock_run,
|
|
):
|
|
mock_cfg.return_value.engine.default = "mlx"
|
|
mock_cfg.return_value.engine.ollama_host = None
|
|
mock_run.return_value = mock.MagicMock(returncode=0)
|
|
|
|
result = runner.invoke(
|
|
cli, ["model", "pull", "qwen3.5:9b", "--engine", "mlx"]
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
mock_run.assert_called_once()
|
|
call_args = mock_run.call_args[0][0]
|
|
assert "huggingface-cli" in call_args
|
|
assert "mlx-community/Qwen3.5-9B-MLX-4bit" in call_args
|
|
|
|
def test_pull_llamacpp_huggingface_cli_not_found(self) -> None:
|
|
from openjarvis.cli import cli
|
|
|
|
runner = CliRunner()
|
|
with (
|
|
mock.patch("openjarvis.cli.model.load_config") as mock_cfg,
|
|
mock.patch("subprocess.run", side_effect=FileNotFoundError),
|
|
):
|
|
mock_cfg.return_value.engine.default = "llamacpp"
|
|
mock_cfg.return_value.engine.ollama_host = None
|
|
|
|
result = runner.invoke(
|
|
cli, ["model", "pull", "qwen3.5:9b", "--engine", "llamacpp"]
|
|
)
|
|
|
|
assert result.exit_code != 0
|
|
assert "huggingface_hub" in result.output or "pip install" in result.output
|