mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 10:15:27 -04:00
Fix/windows llama cpp serve and test upstream (#2669)
* fix: code runner base64, Windows serve paths, endpoint cache clear, copy-log guards, model-picker remove-recent * Revert model-picker 'remove from recent' feature and remove stray PR_DRAFT.md
This commit is contained in:
@@ -342,6 +342,15 @@ def _cached_model_scan_script(model_dirs: list[str] | None = None) -> str:
|
||||
" if f.is_file(): nf += 1; sz += f.stat().st_size",
|
||||
" if f.name.endswith('.incomplete'): ic = True",
|
||||
" snap = os.path.join(cache, d, 'snapshots')",
|
||||
" # Windows HF cache stores files directly in snapshots/; blobs/ may be empty.",
|
||||
" # Fallback: scan snapshots for real files when blobs yielded nothing.",
|
||||
" if sz == 0 and os.path.isdir(snap):",
|
||||
" for sd in os.listdir(snap):",
|
||||
" sf = os.path.join(snap, sd)",
|
||||
" if not os.path.isdir(sf): continue",
|
||||
" for f in os.scandir(sf):",
|
||||
" if f.is_file(): nf += 1; sz += f.stat().st_size",
|
||||
" if f.name.endswith('.incomplete'): ic = True",
|
||||
" is_diffusion = False; gguf_files = []",
|
||||
" if os.path.isdir(snap):",
|
||||
" for sd in os.listdir(snap):",
|
||||
|
||||
+30
-11
@@ -799,6 +799,10 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
existing.name = display_name
|
||||
if supports_tools is not None:
|
||||
existing.supports_tools = supports_tools
|
||||
# Wipe stale model lists so the picker re-probes and discovers
|
||||
# the newly-served model instead of showing the old one.
|
||||
existing.cached_models = None
|
||||
existing.hidden_models = None
|
||||
db.commit()
|
||||
logger.info(f"Updated existing local model endpoint: {base_url}")
|
||||
return existing.id
|
||||
@@ -1089,13 +1093,23 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
runner_lines.append(' ODYSSEUS_OLLAMA_PORT="$_ody_try_port"')
|
||||
runner_lines.append(' break')
|
||||
runner_lines.append(' fi')
|
||||
runner_lines.append(' exec 3<&-; exec 3>&-')
|
||||
runner_lines.append('done')
|
||||
runner_lines.append(' echo "[odysseus] Ollama API ready on port ${ODYSSEUS_OLLAMA_PORT}: ${ODYSSEUS_OLLAMA_URL}"')
|
||||
runner_lines.append(' echo "[odysseus] This task is monitoring an existing Ollama server; stopping it here will not stop an external Docker/system service."')
|
||||
if local_windows:
|
||||
# Windows detached process has no TTY; exec bash -i crashes.
|
||||
# Keep the monitoring task alive with a sleep loop.
|
||||
runner_lines.append(' while true; do sleep 60; done')
|
||||
else:
|
||||
runner_lines.append(' exec bash -i')
|
||||
runner_lines.append('fi')
|
||||
runner_lines.append('if ! command -v ollama &>/dev/null; then')
|
||||
runner_lines.append(' echo "ERROR: Ollama not found on this server. Install it from https://ollama.com/download or `curl -fsSL https://ollama.com/install.sh | sh`."')
|
||||
runner_lines.append(' echo')
|
||||
runner_lines.append(' echo "=== Process exited with code 127 ==="')
|
||||
runner_lines.append(' exec bash -i')
|
||||
if local_windows:
|
||||
runner_lines.append(' exit 127')
|
||||
else:
|
||||
runner_lines.append(' exec bash -i')
|
||||
runner_lines.append('fi')
|
||||
runner_lines.append('ODYSSEUS_OLLAMA_URL="http://${ODYSSEUS_OLLAMA_HOST}:${ODYSSEUS_OLLAMA_PORT}"')
|
||||
if remote and _ollama_host in ("0.0.0.0", "::"):
|
||||
@@ -1103,10 +1117,13 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
runner_lines.append('echo "[odysseus] Ollama has no built-in authentication; expose this only on a trusted LAN/VPN or provide an explicit OLLAMA_HOST with your own access controls."')
|
||||
runner_lines.append('echo "Starting ollama server on ${ODYSSEUS_OLLAMA_HOST}:${ODYSSEUS_OLLAMA_PORT}..."')
|
||||
runner_lines.append('OLLAMA_HOST="${ODYSSEUS_OLLAMA_HOST}:${ODYSSEUS_OLLAMA_PORT}" ollama serve')
|
||||
runner_lines.append('_ody_exit=$?')
|
||||
runner_lines.append('echo')
|
||||
runner_lines.append('echo "=== Process exited with code ${_ody_exit} ==="')
|
||||
runner_lines.append('exec bash -i')
|
||||
if local_windows:
|
||||
_append_serve_exit_code_lines(runner_lines, keep_shell_open=False)
|
||||
else:
|
||||
runner_lines.append('_ody_exit=$?')
|
||||
runner_lines.append('echo')
|
||||
runner_lines.append('echo "=== Process exited with code ${_ody_exit} ==="')
|
||||
runner_lines.append('exec bash -i')
|
||||
elif "vllm serve" in req.cmd:
|
||||
# vLLM is CUDA/ROCm-only and does not run on macOS at all.
|
||||
runner_lines.append('if [ "$(uname -s)" = "Darwin" ]; then')
|
||||
@@ -2104,11 +2121,13 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
"inc=os.path.isdir(blobs) and any(x.endswith('.incomplete') for x in os.listdir(blobs));"
|
||||
"sys.exit(0 if ok and not inc else 1)"
|
||||
)
|
||||
if not remote_host:
|
||||
import sys
|
||||
cmd = [sys.executable, "-c", py, repo_id]
|
||||
else:
|
||||
if remote_host:
|
||||
cmd = ["python3", "-c", py, repo_id]
|
||||
else:
|
||||
# Local Windows: python3 can hit the Microsoft Store stub. Use the
|
||||
# real Python Odysseus is running under (guaranteed to exist).
|
||||
import sys as _sys_local
|
||||
cmd = [_sys_local.executable, "-c", py, repo_id]
|
||||
try:
|
||||
if remote_host:
|
||||
ssh_base = ["ssh"]
|
||||
|
||||
@@ -373,7 +373,11 @@ async def _create_shell(command: str, **kwargs):
|
||||
and env variable expansion errors under Git Bash.
|
||||
"""
|
||||
if IS_WINDOWS:
|
||||
if command.strip().lower().startswith("powershell"):
|
||||
# PowerShell commands (used by the frontend for Windows log-file polling
|
||||
# and session management) must run directly — passing them through
|
||||
# bash -c mangles $env:VAR syntax and breaks the command.
|
||||
cmd_trim = command.strip()
|
||||
if cmd_trim.startswith("powershell") or cmd_trim.startswith("cmd "):
|
||||
return await asyncio.create_subprocess_shell(command, **kwargs)
|
||||
bash = find_bash()
|
||||
if bash:
|
||||
@@ -758,7 +762,7 @@ def setup_shell_routes() -> APIRouter:
|
||||
return {"stdout": "", "stderr": "No command provided", "exit_code": 1}
|
||||
|
||||
logger.info("User shell exec requested: length=%d", len(cmd))
|
||||
result = await _exec_shell(cmd, timeout=EXEC_TIMEOUT)
|
||||
result = await _exec_shell(cmd, timeout=req.timeout if req.timeout is not None else EXEC_TIMEOUT)
|
||||
return result
|
||||
|
||||
@router.post("/api/shell/stream")
|
||||
|
||||
Reference in New Issue
Block a user