fix(ncp): find Ollama on PATH, not only the bundled copy
'ncp doctor' reported a missing Ollama binary on Windows, where winget installs it to %LOCALAPPDATA%\Programs and on PATH rather than into the repo; the same assumption made 'ncp models install' refuse to run there. Adds ollama_bin() mirroring _ollama_bin() in ollama_manager.py. Also renames wait_for_port's early message to READY - 'already running' for a service the same command just started reads like a stale process. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+25
-6
@@ -64,6 +64,19 @@ def http_ok(url: str, timeout: float = 1.0) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def ollama_bin() -> str | None:
|
||||
"""The bundled binary if we have one, else whatever is on PATH.
|
||||
|
||||
Only Linux ships a copy in the repo (bin/fetch-ollama.sh); on Windows the
|
||||
installer gets Ollama from winget, which puts it in %LOCALAPPDATA%\\Programs
|
||||
and on PATH. Checking only the bundled path made `ncp doctor` report a red
|
||||
"Ollama binary missing" on every Windows box, and made `ncp models install`
|
||||
refuse to run there at all. Mirrors _ollama_bin() in ollama_manager.py."""
|
||||
if OLLAMA_BIN.exists():
|
||||
return str(OLLAMA_BIN)
|
||||
return shutil.which("ollama")
|
||||
|
||||
|
||||
def npm() -> str | None:
|
||||
"""npm, resolving through nvm. The bash version sourced ~/.nvm/nvm.sh; a
|
||||
non-login shell has neither, so fall back to globbing the nvm install."""
|
||||
@@ -191,7 +204,11 @@ def check(svc: Service) -> bool:
|
||||
|
||||
def wait_for_port(svc: Service, timeout: int = 30) -> bool:
|
||||
if http_ok(svc.url):
|
||||
print(f" {svc.label} already running (:{svc.port})")
|
||||
# "READY", not "already running": `ncp start` launches memory and backend
|
||||
# together and only then waits on each, so by the time the backend's turn
|
||||
# comes it is normally up - and reporting "already running" for a service
|
||||
# this same command started two seconds ago reads like a stale process.
|
||||
print(f" {svc.label} READY (:{svc.port})")
|
||||
return True
|
||||
for _ in range(timeout):
|
||||
time.sleep(1)
|
||||
@@ -477,8 +494,9 @@ def cmd_doctor() -> None:
|
||||
"Memory database directory writable", "Memory database directory not writable")
|
||||
|
||||
print("\nChecking Ollama...")
|
||||
mark(OLLAMA_BIN.exists(), f"Ollama binary found ({OLLAMA_BIN})",
|
||||
f"Ollama binary missing at {OLLAMA_BIN}")
|
||||
_obin = ollama_bin()
|
||||
mark(bool(_obin), f"Ollama binary found ({_obin})",
|
||||
f"Ollama binary missing (not at {OLLAMA_BIN}, not on PATH)")
|
||||
mark(OLLAMA_MODELS_DIR.is_dir(), f"Ollama models directory found ({OLLAMA_MODELS_DIR})",
|
||||
f"Ollama models directory missing at {OLLAMA_MODELS_DIR}")
|
||||
print()
|
||||
@@ -575,11 +593,12 @@ def cmd_models(action, name) -> None:
|
||||
print("Usage: ncp models install <model>")
|
||||
print("Run 'ncp models available' to see options.")
|
||||
return
|
||||
if not OLLAMA_BIN.exists():
|
||||
print(f"Ollama binary not found at {OLLAMA_BIN}")
|
||||
obin = ollama_bin()
|
||||
if not obin:
|
||||
print(f"Ollama binary not found at {OLLAMA_BIN}, and no 'ollama' on PATH")
|
||||
return
|
||||
print(f"Pulling '{name}' into {OLLAMA_MODELS_DIR} ...\n")
|
||||
subprocess.run([str(OLLAMA_BIN), "pull", name],
|
||||
subprocess.run([obin, "pull", name],
|
||||
env={**os.environ, "OLLAMA_MODELS": str(OLLAMA_MODELS_DIR)})
|
||||
print("\nDone. Run 'ncp models list' to verify.")
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user