mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-07-17 13:18:01 +00:00
Polish mobile UI and editor workflows
This commit is contained in:
@@ -9,6 +9,7 @@ import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.request
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
@@ -400,6 +401,35 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
safe_chmod(key_path.with_suffix(".pub"), 0o644)
|
||||
return {"ok": True, "public_key": _read_cookbook_public_key()}
|
||||
|
||||
class CookbookSshTestRequest(BaseModel):
|
||||
host: str
|
||||
ssh_port: str | None = None
|
||||
|
||||
@router.post("/api/cookbook/test-ssh")
|
||||
async def test_cookbook_ssh(request: Request, req: CookbookSshTestRequest):
|
||||
"""Test a configured Cookbook SSH target without using generic shell exec."""
|
||||
require_admin(request)
|
||||
host = validate_remote_host(req.host)
|
||||
ssh_port = validate_ssh_port(req.ssh_port)
|
||||
try:
|
||||
code, stdout, stderr = await run_ssh_command_async(
|
||||
host,
|
||||
ssh_port,
|
||||
"echo ok",
|
||||
timeout=8,
|
||||
connect_timeout=5,
|
||||
strict_host_key_checking=False,
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
return {"stdout": "", "stderr": "SSH test timed out", "exit_code": 124}
|
||||
except Exception as e:
|
||||
return {"stdout": "", "stderr": str(e), "exit_code": -1}
|
||||
return {
|
||||
"stdout": stdout.decode("utf-8", errors="replace"),
|
||||
"stderr": stderr.decode("utf-8", errors="replace"),
|
||||
"exit_code": code,
|
||||
}
|
||||
|
||||
def _needs_binary(cmd: str, binary: str) -> bool:
|
||||
return bool(re.search(rf"(^|[\s;&|()]){re.escape(binary)}($|[\s;&|()])", cmd or ""))
|
||||
|
||||
@@ -1119,6 +1149,22 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
try:
|
||||
ep = db.query(_ME).filter(_ME.id == endpoint_id).first()
|
||||
if ep:
|
||||
# A scheduled serve can leave old non-zero exit markers
|
||||
# in tmux scrollback while the current OpenAI endpoint is
|
||||
# actually alive. Verify reachability before deleting the
|
||||
# endpoint row; otherwise chats fall back even though the
|
||||
# served model is ready.
|
||||
try:
|
||||
probe_url = ep.base_url.rstrip("/") + "/models"
|
||||
with urllib.request.urlopen(probe_url, timeout=3) as resp:
|
||||
if 200 <= getattr(resp, "status", 0) < 300:
|
||||
logger.info(
|
||||
f"crash-watchdog: serve {session_id} has exit marker {exit_code} "
|
||||
f"but endpoint {ep.id} is reachable; leaving it registered"
|
||||
)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
logger.info(
|
||||
f"crash-watchdog: dropping endpoint {endpoint_id} "
|
||||
f"({ep.name} @ {ep.base_url}) — serve exited {exit_code}"
|
||||
@@ -1205,6 +1251,8 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
existing.is_enabled = True
|
||||
existing.model_type = "llm"
|
||||
existing.name = display_name
|
||||
existing.endpoint_kind = "local"
|
||||
existing.model_refresh_mode = "auto"
|
||||
if is_ollama_endpoint:
|
||||
existing.endpoint_kind = "ollama"
|
||||
if pinned_models:
|
||||
@@ -1252,7 +1300,8 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
api_key=None,
|
||||
is_enabled=True,
|
||||
model_type="llm",
|
||||
endpoint_kind="ollama" if is_ollama_endpoint else "auto",
|
||||
endpoint_kind="ollama" if is_ollama_endpoint else "local",
|
||||
model_refresh_mode="auto",
|
||||
cached_models=json.dumps(pinned_models) if pinned_models else None,
|
||||
pinned_models=json.dumps(pinned_models) if pinned_models else None,
|
||||
supports_tools=supports_tools,
|
||||
|
||||
Reference in New Issue
Block a user