Show retrain progress in Android

This commit is contained in:
Codex
2026-06-27 09:18:18 +03:00
parent f8611a1c3f
commit b6d616ec2a
6 changed files with 192 additions and 29 deletions
+7
View File
@@ -144,6 +144,13 @@ def create_app(settings: Settings | None = None) -> FastAPI:
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
@app.post("/api/training/jobs/{job_id}/progress")
async def training_progress(job_id: str, payload: dict[str, Any] | None = None) -> dict[str, Any]:
try:
return training.progress(job_id, payload)
except ValueError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
@app.post("/api/training/jobs/{job_id}/complete")
async def training_complete(job_id: str, payload: dict[str, Any] | None = None) -> dict[str, Any]:
try:
+32
View File
@@ -139,6 +139,25 @@ class TrainingCoordinator:
self._save_state(state)
return {"complete": True, "name": name, "sha256": sha256}
def progress(self, job_id: str, payload: dict[str, Any] | None = None) -> dict[str, Any]:
payload = payload or {}
with self._lock:
state = self._load_state()
job = self._job_by_id(state, job_id)
if job is None:
raise ValueError(f"training job not found: {job_id}")
if isinstance(payload.get("worker"), dict):
state["worker"] = self._worker_from_payload(payload["worker"])
job["status"] = str(payload.get("status") or job.get("status") or "running")
job["phase"] = str(payload.get("phase") or job.get("phase") or "running")
job["message"] = str(payload.get("message") or job.get("message") or "")
job["progress_percent"] = _coerce_percent(payload.get("progress_percent"), job.get("progress_percent", 0))
job["updated_at"] = _now()
if isinstance(payload.get("details"), dict):
job["details"] = payload["details"]
self._save_state(state)
return {"ok": True, "job": job, "status": self._public_status(state)}
def complete(self, job_id: str, payload: dict[str, Any] | None = None) -> dict[str, Any]:
payload = payload or {}
with self._lock:
@@ -148,6 +167,8 @@ class TrainingCoordinator:
raise ValueError(f"training job not found: {job_id}")
success = bool(payload.get("success", payload.get("status") == "completed"))
job["status"] = "completed" if success else "failed"
job["phase"] = "completed" if success else "failed"
job["progress_percent"] = 100 if success else _coerce_percent(payload.get("progress_percent"), job.get("progress_percent", 0))
job["completed_at"] = _now()
job["message"] = str(payload.get("message") or "")
if isinstance(payload.get("summary"), dict):
@@ -257,6 +278,17 @@ def _parse_time(value: str) -> datetime | None:
return None
def _coerce_percent(value: Any, default: Any = 0) -> int:
try:
number = int(float(value))
except (TypeError, ValueError):
try:
number = int(float(default))
except (TypeError, ValueError):
number = 0
return max(0, min(number, 100))
def _remove_tree(path: Path) -> None:
if not path.exists():
return