fix(cookbook): don't infer server OS from the browser's user-agent (#3223)

_getPlatform('local') fell back to navigator.userAgent to decide the
*server's* platform. On a Mac/Linux homeserver opened from a Windows
browser this returned 'windows', so the GGUF serve builder emitted the
Windows python-only shape (`python -m llama_cpp.server`, no
`llama-server ||` fallback). That command fails on the Unix host with
"No module named llama_cpp" even though native llama-server is installed,
and the diagnosis then misleadingly tells the user to pip-install
llama-cpp-python.

Trust the server-side hardware probe over the user-agent: a non-empty
probe backend (metal/cuda/rocm/cpu_*) means a Unix server; local Windows
instead carries platform:"windows" which already sets _envState.platform
and short-circuits. Only fall back to the browser hint when there is no
server-side signal at all. Keeps #1389/#2961's local-Windows path intact.

Fixes #3221

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Léo
2026-06-07 13:20:05 +02:00
committed by GitHub
parent 2149f0fb67
commit 573d431399
+16 -2
View File
@@ -162,13 +162,27 @@ function _getPort(hostOrTask) {
/** Get platform for a given host (or task object). Returns 'windows', 'termux', 'linux', or '' */
export function _getPlatform(hostOrTask) {
const isWinBrowser = (window.navigator.userAgent || window.navigator.platform || '').toLowerCase().includes('win');
// The browser's OS is NOT the server's OS when the UI is opened remotely —
// e.g. a Windows browser driving a Mac/Linux homeserver. Trusting the
// user-agent there makes the serve builder emit the Windows python-only
// shape (`python -m llama_cpp.server`, no `llama-server ||` fallback), which
// then fails on the actual Unix server. The local hardware probe is
// authoritative: it reports a backend (metal/cuda/rocm/cpu_*) for any Unix
// server and carries platform:"windows" for local Windows (which sets
// _envState.platform, short-circuiting below). So only fall back to the
// browser hint when we have no server-side signal at all.
const localPlatform = () => {
if (_envState.platform) return _envState.platform;
if (String(_hwfitCache?.system?.backend || '')) return '';
return isWinBrowser ? 'windows' : '';
};
if (!hostOrTask || hostOrTask === 'local') {
return _envState.platform || (isWinBrowser ? 'windows' : '');
return localPlatform();
}
if (typeof hostOrTask === 'object') {
const h = hostOrTask.remoteHost;
if (!h || h === 'local') {
return hostOrTask.platform || _envState.platform || (isWinBrowser ? 'windows' : '');
return hostOrTask.platform || localPlatform();
}
return hostOrTask.platform || _getPlatform(h);
}