Fix all linter issues
This commit is contained in:
parent
fbd4b6c5e8
commit
d4a2ace913
10 changed files with 2989 additions and 28 deletions
|
|
@ -60,7 +60,7 @@ agent's own shell command line and kills the session.
|
|||
while the UI switch is on, reaps stale locks by `who` marker on startup)
|
||||
+ lact plugin (shells out to `lact cli`: per-GPU profile dropdown with
|
||||
set/reload, active profile polled every 5 s, GPU names shortened with
|
||||
`app/collect/gpu.py:_shorten` like the overview card).
|
||||
`app/collect/gpu.py:shorten` like the overview card).
|
||||
|
||||
## Conventions
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
from app import routers # noqa: F401
|
||||
|
|
@ -16,7 +16,7 @@ def _read(path: str) -> str | None:
|
|||
return None
|
||||
|
||||
|
||||
def _shorten(name: str) -> str:
|
||||
def shorten(name: str) -> str:
|
||||
name = re.sub(r"\s*\(rev.*\)$", "", name).strip()
|
||||
groups = re.findall(r"\[([^\]]+)\]", name)
|
||||
if len(groups) >= 2:
|
||||
|
|
@ -42,7 +42,7 @@ def _gpu_name() -> str:
|
|||
).stdout
|
||||
for line in out.splitlines():
|
||||
if "VGA" in line or "3D controller" in line:
|
||||
_name_cache = _shorten(line.split(":", 2)[-1].strip())
|
||||
_name_cache = shorten(line.split(":", 2)[-1].strip())
|
||||
break
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
from functools import lru_cache
|
||||
from typing import ClassVar
|
||||
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_prefix="DASH_", env_file=".env", extra="ignore")
|
||||
model_config: ClassVar[SettingsConfigDict] = SettingsConfigDict(env_prefix="DASH_", env_file=".env", extra="ignore")
|
||||
|
||||
host: str = "127.0.0.1"
|
||||
port: int = 8501
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@ async def lifespan(app: FastAPI):
|
|||
pass
|
||||
|
||||
|
||||
async def index():
|
||||
return HTMLResponse(render("index.html", hostname=socket.gethostname()))
|
||||
|
||||
|
||||
def create_app() -> FastAPI:
|
||||
app = FastAPI(title="Dashboard", lifespan=lifespan)
|
||||
app.mount("/static", StaticFiles(directory=BASE / "static"), name="static")
|
||||
|
|
@ -46,10 +50,7 @@ def create_app() -> FastAPI:
|
|||
app.include_router(r)
|
||||
for r in PLUGIN_ROUTERS:
|
||||
app.include_router(r)
|
||||
|
||||
@app.get("/", include_in_schema=False)
|
||||
async def index():
|
||||
return HTMLResponse(render("index.html", hostname=socket.gethostname()))
|
||||
_ = app.get("/", include_in_schema=False)(index)
|
||||
|
||||
return app
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import asyncio
|
||||
import re
|
||||
import time
|
||||
from typing import Any
|
||||
from typing import Annotated, Any
|
||||
|
||||
from fastapi import APIRouter, Form
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
||||
from app.collect.gpu import _shorten
|
||||
from app.collect.gpu import shorten
|
||||
from app.plugins.base import Plugin
|
||||
from app.render import render
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ def _parse_gpus(out: str) -> list[dict[str, str]]:
|
|||
gpu_type = re.search(r"\[([^\]]*)\]\s*$", rest)
|
||||
gpus.append({
|
||||
"id": m.group(1),
|
||||
"name": _shorten(name.group(1)) if name else rest.strip(),
|
||||
"name": shorten(name.group(1)) if name else rest.strip(),
|
||||
"type": gpu_type.group(1) if gpu_type else "",
|
||||
})
|
||||
return gpus
|
||||
|
|
@ -126,7 +126,7 @@ async def state():
|
|||
|
||||
|
||||
@router.post("/set")
|
||||
async def set_profile(gpu_id: str = Form(...), profile: str = Form(...)):
|
||||
async def set_profile(gpu_id: Annotated[str, Form()], profile: Annotated[str, Form()]):
|
||||
async with _set_lock:
|
||||
data = await _gather(with_profiles=True, force_gpus=True)
|
||||
if data["error"]:
|
||||
|
|
@ -145,7 +145,7 @@ async def set_profile(gpu_id: str = Form(...), profile: str = Form(...)):
|
|||
|
||||
|
||||
@router.post("/reload")
|
||||
async def reload(gpu_id: str | None = Form(None)):
|
||||
async def reload(gpu_id: Annotated[str | None, Form()] = None):
|
||||
_ = gpu_id
|
||||
return HTMLResponse(await _skeleton(message="profiles refreshed"))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Any
|
||||
from typing import Annotated, Any
|
||||
|
||||
import httpx
|
||||
from fastapi import APIRouter, Form
|
||||
|
|
@ -12,7 +12,7 @@ router = APIRouter(prefix="/api/plugins/llamacpp", tags=["plugins"])
|
|||
|
||||
|
||||
def _headers(settings: Settings) -> dict[str, str]:
|
||||
h = {}
|
||||
h: dict[str, str] = {}
|
||||
if settings.llama_api_key:
|
||||
h["Authorization"] = f"Bearer {settings.llama_api_key}"
|
||||
return h
|
||||
|
|
@ -37,6 +37,7 @@ async def gather_status() -> dict[str, Any]:
|
|||
"models": [],
|
||||
"error": None,
|
||||
}
|
||||
models: list[dict[str, str | bool | float]] = []
|
||||
try:
|
||||
async with _client() as client:
|
||||
try:
|
||||
|
|
@ -62,12 +63,13 @@ async def gather_status() -> dict[str, Any]:
|
|||
done = sum(p.get("done", 0) for p in prog.values())
|
||||
total = sum(p.get("total", 1) for p in prog.values())
|
||||
item["progress"] = round(done / total * 100, 1) if total else 0.0
|
||||
status["models"].append(item)
|
||||
status["models"].sort(key=lambda m: m["id"])
|
||||
models.append(item)
|
||||
models.sort(key=lambda m: m["id"])
|
||||
except httpx.HTTPError as e:
|
||||
status["error"] = f"unreachable: {e.__class__.__name__}"
|
||||
except Exception as e: # noqa
|
||||
status["error"] = str(e)[:200]
|
||||
status["models"] = models
|
||||
return status
|
||||
|
||||
|
||||
|
|
@ -117,7 +119,7 @@ async def state():
|
|||
|
||||
|
||||
@router.post("/load")
|
||||
async def load(model: str = Form(...)):
|
||||
async def load(model: Annotated[str, Form()]):
|
||||
ok, err = await _action("/models/load", model)
|
||||
return HTMLResponse(
|
||||
await _skeleton(
|
||||
|
|
@ -128,7 +130,7 @@ async def load(model: str = Form(...)):
|
|||
|
||||
|
||||
@router.post("/unload")
|
||||
async def unload(model: str = Form(...)):
|
||||
async def unload(model: Annotated[str, Form()]):
|
||||
ok, err = await _action("/models/unload", model)
|
||||
return HTMLResponse(
|
||||
await _skeleton(
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import asyncio
|
|||
import json
|
||||
import os
|
||||
import signal
|
||||
from typing import Any
|
||||
from typing import Annotated, Any, cast
|
||||
|
||||
from fastapi import APIRouter, Form
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
|
@ -45,7 +45,7 @@ async def _list() -> tuple[list[dict[str, Any]], str]:
|
|||
return [], "could not parse systemd-inhibit output"
|
||||
if not isinstance(data, list):
|
||||
return [], "unexpected systemd-inhibit output"
|
||||
items: list[dict[str, Any]] = [e for e in data if isinstance(e, dict)]
|
||||
items: list[dict[str, Any]] = [e for e in cast("list[Any]", data) if isinstance(e, dict)]
|
||||
return items, ""
|
||||
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ async def state():
|
|||
|
||||
|
||||
@router.post("/toggle")
|
||||
async def toggle(on: str | None = Form(None)):
|
||||
async def toggle(on: Annotated[str | None, Form()] = None):
|
||||
async with _toggle_lock:
|
||||
if on and _holder is None:
|
||||
err = await _acquire()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Any
|
||||
from typing import Annotated, Any
|
||||
|
||||
from fastapi import APIRouter, Form
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
|
@ -95,10 +95,10 @@ async def service_detail(unit: str):
|
|||
@router.post("/{unit}/action")
|
||||
async def service_action(
|
||||
unit: str,
|
||||
action: str = Form(...),
|
||||
q: str = Form(""),
|
||||
sort: str = Form("name"),
|
||||
order: str = Form("asc"),
|
||||
action: Annotated[str, Form()],
|
||||
q: Annotated[str, Form()] = "",
|
||||
sort: Annotated[str, Form()] = "name",
|
||||
order: Annotated[str, Form()] = "asc",
|
||||
):
|
||||
error = None
|
||||
try:
|
||||
|
|
|
|||
2958
opencode/opencode_session_linter_issues_2026-08-30.txt
Normal file
2958
opencode/opencode_session_linter_issues_2026-08-30.txt
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue