mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-08-14 00:47:52 +00:00
fix: detect total RAM on Windows via GlobalMemoryStatusEx
`_total_ram_gb()` had branches for Darwin (sysctl) and Linux (/proc/meminfo) but no Windows path, so `jarvis init` reported "0.0 GB RAM" on every Windows host. The downstream `recommend_model()` then fell back to VRAM-only sizing, often selecting a smaller tier than the system can actually run. Add a Windows branch that calls `GlobalMemoryStatusEx` via ctypes — no new dependency. Add a platform-skip-aware test for each OS branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
krypticmouse
co-authored by
Claude Opus 4.7
parent
8b5a304222
commit
31efd9e672
@@ -188,13 +188,34 @@ def _total_ram_gb() -> float:
|
||||
if platform.system() == "Darwin":
|
||||
raw = _run_cmd(["sysctl", "-n", "hw.memsize"])
|
||||
return round(int(raw) / (1024**3), 1) if raw else 0.0
|
||||
if platform.system() == "Windows":
|
||||
import ctypes
|
||||
|
||||
class _MemoryStatusEx(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("dwLength", ctypes.c_ulong),
|
||||
("dwMemoryLoad", ctypes.c_ulong),
|
||||
("ullTotalPhys", ctypes.c_ulonglong),
|
||||
("ullAvailPhys", ctypes.c_ulonglong),
|
||||
("ullTotalPageFile", ctypes.c_ulonglong),
|
||||
("ullAvailPageFile", ctypes.c_ulonglong),
|
||||
("ullTotalVirtual", ctypes.c_ulonglong),
|
||||
("ullAvailVirtual", ctypes.c_ulonglong),
|
||||
("sullAvailExtendedVirtual", ctypes.c_ulonglong),
|
||||
]
|
||||
|
||||
stat = _MemoryStatusEx()
|
||||
stat.dwLength = ctypes.sizeof(_MemoryStatusEx)
|
||||
if ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat)):
|
||||
return round(stat.ullTotalPhys / (1024**3), 1)
|
||||
return 0.0
|
||||
meminfo = Path("/proc/meminfo")
|
||||
if meminfo.exists():
|
||||
for line in meminfo.read_text().splitlines():
|
||||
if line.startswith("MemTotal"):
|
||||
kb = int(line.split()[1])
|
||||
return round(kb / (1024**2), 1)
|
||||
except (OSError, ValueError):
|
||||
except (OSError, ValueError, AttributeError):
|
||||
pass
|
||||
return 0.0
|
||||
|
||||
|
||||
@@ -3,13 +3,17 @@ and engine recommendation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from openjarvis.core.config import (
|
||||
GpuInfo,
|
||||
_detect_amd_gpu,
|
||||
_detect_apple_gpu,
|
||||
_detect_nvidia_gpu,
|
||||
_total_ram_gb,
|
||||
recommend_engine,
|
||||
)
|
||||
|
||||
@@ -75,6 +79,31 @@ class TestDetectHardware:
|
||||
assert _detect_apple_gpu() is None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# RAM detection
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestTotalRamGb:
|
||||
"""Tests for _total_ram_gb() across platforms."""
|
||||
|
||||
@pytest.mark.skipif(sys.platform != "win32", reason="Requires Windows")
|
||||
def test_total_ram_gb_windows(self):
|
||||
"""On Windows, GlobalMemoryStatusEx must return a positive RAM value."""
|
||||
ram = _total_ram_gb()
|
||||
assert ram > 0, f"Expected > 0 GB on Windows, got {ram}"
|
||||
|
||||
@pytest.mark.skipif(sys.platform != "darwin", reason="Requires macOS")
|
||||
def test_total_ram_gb_darwin(self):
|
||||
ram = _total_ram_gb()
|
||||
assert ram > 0, f"Expected > 0 GB on macOS, got {ram}"
|
||||
|
||||
@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Requires Linux")
|
||||
def test_total_ram_gb_linux(self):
|
||||
ram = _total_ram_gb()
|
||||
assert ram > 0, f"Expected > 0 GB on Linux, got {ram}"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Engine recommendation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user