Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions routes/cookbook_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,30 @@ class ServeRequest(BaseModel):
platform: str | None = None # "linux", "termux", or "windows"


def _serve_gpu_pin_var(env_prefix: str | None, cmd: str | None) -> str:
"""ROCm/HIP stacks need HIP_VISIBLE_DEVICES; NVIDIA uses CUDA_VISIBLE_DEVICES."""
blob = f"{env_prefix or ''} {cmd or ''}"
if re.search(r"HIP_VISIBLE_DEVICES|\brocm\b|hipconfig", blob, re.I):
return "HIP_VISIBLE_DEVICES"
return "CUDA_VISIBLE_DEVICES"


def _serve_gpu_export_line(
gpus: str | None,
env_prefix: str | None,
cmd: str | None,
*,
windows: bool = False,
) -> str | None:
g = (gpus or "").strip()
if not g:
return None
var = _serve_gpu_pin_var(env_prefix, cmd)
if windows:
return f"$env:{var} = '{g.replace(chr(39), chr(39)+chr(39))}'"
return f"export {var}='{_bash_squote(g)}'"


def _parse_serve_phase(snapshot: str, task_type: str = "serve") -> dict:
"""Parse a tmux snapshot of a serve task into structured phase info.

Expand Down
10 changes: 7 additions & 3 deletions routes/cookbook_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
_user_shell_path_bootstrap, _venv_safe_local_pip_install_cmd,
_append_pip_install_runner_lines, _pip_install_command_without_break_system_packages,
_normalize_llama_cpp_python_cache_types,
ModelDownloadRequest, ServeRequest,
ModelDownloadRequest, ServeRequest, _serve_gpu_export_line,
)

_HF_TOKEN_STATUS_SNIPPET = (
Expand Down Expand Up @@ -2008,7 +2008,9 @@ async def model_serve(request: Request, req: ServeRequest):
if req.hf_token:
ps_lines.append(f"$env:HF_TOKEN = '{_ps_squote(req.hf_token)}'")
if req.gpus:
ps_lines.append(f"$env:CUDA_VISIBLE_DEVICES = '{req.gpus}'")
_gpu_line = _serve_gpu_export_line(req.gpus, req.env_prefix, req.cmd, windows=True)
if _gpu_line:
ps_lines.append(_gpu_line)
if req.env_prefix:
ps_lines.append(_safe_env_prefix(req.env_prefix))
# Auto-install ollama if the command uses it
Expand Down Expand Up @@ -2082,7 +2084,9 @@ async def model_serve(request: Request, req: ServeRequest):
if req.hf_token:
runner_lines.append(f"export HF_TOKEN='{_bash_squote(req.hf_token)}'")
if req.gpus:
runner_lines.append(f"export CUDA_VISIBLE_DEVICES='{req.gpus}'")
_gpu_line = _serve_gpu_export_line(req.gpus, req.env_prefix, req.cmd, windows=False)
if _gpu_line:
runner_lines.append(_gpu_line)
if req.env_prefix:
runner_lines.append(_safe_env_prefix(req.env_prefix))
else:
Expand Down
39 changes: 39 additions & 0 deletions tests/test_batch4_contrib_fixes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Regression tests for fourth contribution batch."""
import pytest

from routes.cookbook_helpers import _serve_gpu_pin_var, _serve_gpu_export_line
from routes.model_routes import _is_discovery_only_provider, _explicit_model_list_timeout
from services.hwfit.fit import _lookup_bandwidth
from core.session_manager import _content_for_db_storage


def test_hwfit_laptop_4090_bandwidth():
bw = _lookup_bandwidth("NVIDIA GeForce RTX 4090 Laptop GPU")
assert bw == 504


def test_openrouter_discovery_only():
assert _is_discovery_only_provider("openrouter") is True
assert _is_discovery_only_provider("anthropic") is False


def test_ollama_private_lan_timeout():
t = _explicit_model_list_timeout("http://192.168.0.5:11434/v1", "auto", None)
assert t >= 20.0


def test_serve_gpu_hip_when_env_prefix_has_hip():
assert _serve_gpu_pin_var("HIP_VISIBLE_DEVICES=1", "llama-server --model x") == "HIP_VISIBLE_DEVICES"
line = _serve_gpu_export_line("1", "HIP_VISIBLE_DEVICES=1", "llama-server", windows=False)
assert line and "HIP_VISIBLE_DEVICES" in line and "1" in line


def test_storage_strips_inline_image_base64():
blocks = [
{"type": "text", "text": "hi"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,AAAA"}},
]
out = _content_for_db_storage(blocks)
assert isinstance(out, list)
assert out[1]["type"] == "text"
assert "attachment" in out[1]["text"]