Trim and tighten code comments and docstrings across the repository. Comment-only: every changed file verified code-identical to main via AST/token comparison.
Trim and tighten code comments and docstrings across studio/ Python. Comment-only: every changed file verified code-identical to main via AST/token comparison.
Raise ruff line-length to 100 and extend the local pre-commit format pipeline (def-signature magic-comma normalization, short multi-line assert collapse, kwarg '=' spacing, blank-line-after-short-import removal, adjacent string-literal / f-string+plain merge, redundant-pass pruning). Every transform re-checks the file AST and is dropped if it would differ; the whole-repo reformat is verified AST-identical per file and idempotent.
* tests/studio: end-to-end Windows GPU detection mock test (#5106)
Locks in the combined fix from #5322 + #5324 with a synthetic
Windows scenario that CI runners without GPUs can execute. The
test packs the real PyPI win_amd64 wheel layouts (cu12 modular and
the new unsuffixed cu13 nvidia/cu13/bin/x86_64 layout) plus the
exact filename set of the upstream b9103 cudart-llama-bin-win-cuda
bundles, then mocks nvidia-smi output and asserts that:
* Studio's nvidia-smi probe parses the CSV and reports the GPU.
* After PR #5322 the install_dir/build/bin/Release/ tree contains
all three cudart bundle DLLs alongside llama-server.exe.
* After PR #5324 the PATH built by start_llama_server's win32
branch lists pip nvidia + torch/lib dirs in addition to the
binary_dir.
* cudart64_X.dll, cublas64_X.dll, and cublasLt64_X.dll are
each reachable from at least one PATH entry, with cudart
specifically reachable from BOTH the install dir and a pip
nvidia dir (defence in depth).
* Bare venvs without pip nvidia wheels still work via #5322's
binary_dir drop; pre-#5322 installs still work via #5324's
PATH augmentation.
* A reconstructed pre-PR scenario (cudart absent from binary_dir
and pip dirs not on PATH) leaves cudart unreachable, confirming
the test would catch a future regression.
Bonus housekeeping in studio/install_llama_prebuilt.py: drop the
pointless f-prefix on the literal "llama-" in the
windows_cuda_attempts pairing guard (no behaviour change; lint
nit flagged in the post-merge review).
The mocks model real artifact contents I verified empirically:
* pip download nvidia-cuda-runtime --platform win_amd64
produces nvidia/cu13/bin/x86_64/cudart64_13.dll.
* unzip on the b9103 cudart-llama-bin-win-cuda-13.1-x64.zip
produces exactly cudart64_13.dll + cublas64_13.dll +
cublasLt64_13.dll, no executables.
* objdump -p on the b9103 ggml-cuda.dll shows a static PE
import on cublas64_13.dll (the root cause of #5106 when
cublas64_13.dll is unreachable).
Refs #5106#5322#5324
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* test_5106_windows_gpu_detection_mock: don't shadow real httpx
This file's name sorts before every other file in studio/backend/tests/
(starts with the digit '5'), so pytest collects it first. The previous
``sys.modules.setdefault("httpx", _httpx_stub)`` ran before any other
test imported real httpx, which meant the stub permanently shadowed
the real module for the rest of the collection. Tests that did
``from httpx import HTTPError, Response`` (test_anthropic_messages,
test_browse_folders_route, test_training_*, etc) then failed at
collection with ``ImportError: cannot import name 'HTTPError'``
because the stub did not define those names. The existing
test_llama_cpp_windows_nvidia_path.py did not trigger the same issue
because it sorts after test_a* / test_b* / etc, by which point the
real httpx has already been imported and setdefault is a no-op.
Switch the stub installation to ``importlib.util.find_spec(name) is
None`` so we only fall back to the stub when the real module truly is
not installed. Backend CI installs httpx, structlog, and the
studio/backend/loggers package is reachable via the sys.path
augmentation a few lines above, so on CI all three find_spec calls
succeed and no stubs are installed at all.
Also add HTTPError and Response to the stub module for the offline
case, so anyone running this test outside CI with httpx absent still
gets a stub that satisfies the broader test suite's imports.
Refs #5106
* test_5106 + llama_cpp: extract win32 PATH helper and harden the regression test
Follow-up to PR #5376's review feedback. Three real findings from the
bot reviewers, plus one stale one.
1. (codex P2 line 201, gemini medium line 209) The regression test's
_build_path_dirs_like_start_llama_server hand-copied the win32
branch of LlamaCppBackend.start_llama_server, so a future drop or
reorder of _windows_pip_nvidia_dll_dirs(sys.prefix) in production
would have passed the test silently.
Extract a new staticmethod LlamaCppBackend._build_windows_path_dirs
(binary_dir, prefix, cuda_path). Production start_llama_server now
calls this helper. The test's wrapper is reduced to a one-line
delegate that forwards to the staticmethod, so the regression
asserts against the exact production logic instead of a parallel
copy of it.
2. (codex P2 line 245) test_nvidia_smi_probe_reports_synthetic_gpu did
not clear CUDA_VISIBLE_DEVICES. On a shared GPU runner with the
variable set in the parent shell, _get_gpu_free_memory() filters
the mocked CSV and returns [] or falls through to the torch
fallback. Cleared CUDA_VISIBLE_DEVICES and NVIDIA_VISIBLE_DEVICES
via monkeypatch.delenv(..., raising=False).
3. (codex P2 line 66) _maybe_stub gated on importlib.util.find_spec
("loggers"), which returns a spec because studio/backend/loggers/
is on sys.path. But the actual import chain loads
loggers/handlers.py which does `from fastapi import Request,
Response` at module load. In a lightweight env without fastapi
installed, the stub never lands and `from core.inference.llama_cpp
import LlamaCppBackend` raises during collection. Switched
_maybe_stub to a real import attempt under try / except ImportError
so the stub falls into place when the package is discoverable but
not importable. CI has fastapi so this is purely a developer-
machine ergonomics fix.
The fourth comment (codex P1 line 85 "Keep the httpx stub from leaking
across tests") was already addressed by 7437e735, which replaced the
unconditional sys.modules.setdefault with the find_spec-gated
_maybe_stub. No code change needed.
Production behaviour is unchanged: _build_windows_path_dirs returns
exactly the same ordering start_llama_server used inline
([binary_dir, *pip_dirs, cuda_bin?, cuda_bin_x64?]).
Verification (run inside studio/backend):
pytest tests/test_5106_windows_gpu_detection_mock.py -v
-> 10 passed
pytest tests/test_llama_cpp_*.py tests/test_llama_server_args.py
tests/test_5106_windows_gpu_detection_mock.py -q
-> 171 passed
CUDA_VISIBLE_DEVICES=1 pytest tests/test_5106_windows_gpu_detection_mock.py::TestWindowsGpuDetectionAfter5106Fix::test_nvidia_smi_probe_reports_synthetic_gpu
-> 1 passed
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Rename Windows GPU detection test to a generic filename and trim comments
- studio/backend/tests/test_5106_windows_gpu_detection_mock.py
-> studio/backend/tests/test_windows_gpu_detection_mock.py
The file is the generic regression suite for Windows GPU detection;
encoding the issue number in the filename is noise.
- Shorten module docstring, helper docstrings, per-test docstrings and
inline comments in the renamed test file. No behaviour change,
all 10 cases still pass.
- Shorten the _build_windows_path_dirs docstring in
studio/backend/core/inference/llama_cpp.py and update the test-path
reference; trim the win32 call-site comment to one line.
Local verification:
- pytest studio/backend/tests/test_windows_gpu_detection_mock.py -- 10 passed.
- pytest studio/backend/tests/test_llama_cpp_windows_nvidia_path.py
studio/backend/tests/test_llama_server_args.py
studio/backend/tests/test_windows_gpu_detection_mock.py -- 110 passed.
* Studio: harden _wait_for_health against transient httpx ReadError
The probe loop in LlamaCppBackend._wait_for_health only caught
ConnectError and TimeoutException. On Windows, when llama-server.exe
accepts the TCP probe and then dies before sending HTTP headers, the
peer process RST closes the socket. httpx maps this to ReadError
("WinError 10054 -- An existing connection was forcibly closed by the
remote host"), which fell through the except clause and bubbled out of
_wait_for_health, the routes/inference.py load_model handler, and back
to /api/inference/load as an opaque 500.
The crash diagnostic Studio actually wants to surface lives on the
self._process.poll() branch at the top of the loop body: "llama-server
exited with code X. Output: ...". We never reached that branch on the
WinError 10054 path because the very first probe blew up.
Expand the except to also swallow ReadError and RemoteProtocolError so
the next 0.5-second iteration runs the poll() branch. Outcomes:
* Process really died: structured exit-code + last-stdout log line.
* Single transient probe blip: silently retried; load succeeds.
Adds studio/backend/tests/test_llama_cpp_wait_for_health.py with five
cases covering happy-path 200, transient ReadError + dead process,
RemoteProtocolError + dead process, ConnectError cycling until success,
and dead process before the first probe. The new cases would have
failed against the old except clause -- ReadError / RemoteProtocolError
would have propagated instead of returning False.
Found while triaging the Windows Studio GGUF CI flake on this PR's
5a6ddc34 push: llama-server.exe (b9203 prebuilt) crashed within 2.2 s of
launch on the GPU-less runner, and Studio reported "WinError 10054"
instead of an upstream-tag-attributable exit-code line.
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: danielhanchen <michaelhan2050@gmail.com>