fix: use sys.executable for Cookbook model cache scan on Windows (#627)

Windows has 'App Execution Aliases' that can make shutil.which('python3')
and shutil.which('python') resolve to a Microsoft Store stub instead of
real Python -- even when Python is properly installed. The stub outputs:

  'Python was not found; run without arguments to install from the
   Microsoft Store, or disable this shortcut from Settings > Apps >
   Advanced app settings > App execution aliases.'

and exits 9009, producing empty stdout. The JSON parse of the local
model cache scan then fails with 'Expecting value: line 1 column 1
(char 0)', and the Cookbook model list shows nothing.

Fix: prefer sys.executable as the interpreter for the local scan.
Odysseus already runs inside its own venv, so sys.executable always
points to the real venv Python and bypasses PATH / Store alias lookup
entirely. which_tool() is kept as a fallback.

Cross-platform: sys.executable works identically on Linux and macOS
(returns the real interpreter path), so this change is safe everywhere.
This commit is contained in:
IBR-41379
2026-06-02 08:59:40 +05:30
committed by GitHub
parent 25dcb1b10f
commit 385c3c3cf3

View File

@@ -677,11 +677,14 @@ def setup_cookbook_routes() -> APIRouter:
cwd=str(Path.home()),
)
else:
# LOCAL scan: run the interpreter directly. `python3` isn't a thing on
# Windows (it's `python`/`py`), and shell single-quoting of the path
# doesn't survive cmd.exe — so resolve the interpreter and exec it
# with the script path as an argv element (no shell quoting needed).
local_py = (
# LOCAL scan: use sys.executable (the venv Python Odysseus is already
# running under) — it's guaranteed real Python on all platforms.
# Falling back to which_tool on Windows risks hitting the Microsoft
# Store stub alias for "python3"/"python", which prints
# "Python was not found; run without arguments to install from the
# Microsoft Store" and exits 9009, producing empty stdout and a
# JSON parse error. sys.executable bypasses PATH entirely.
local_py = sys.executable or (
which_tool("python3") or which_tool("python")
or which_tool("py") or "python"
)