feat: 更新后端平台模块、前端组件及构建产物,新增工作计划文档

- 更新 backend 平台 API endpoints 及 platform_store
- 更新前端 ComputeNodesView、DataProcessCreateView、FineTuneCreateView 等组件
- 更新前端 API 模块(compute、fineTune)
- 重构 frontend/dist 构建产物(新 hash)
- 新增 docs/2026-07-24-work-plan.md 工作计划文档

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
wuyongtao
2026-07-24 10:27:52 +08:00
parent b28cfbc6fa
commit 2b10c013ce
151 changed files with 925 additions and 181 deletions

View File

@@ -1474,25 +1474,40 @@ class PlatformStore:
def prepare_compute_job_payload(self, task_id: str, payload: dict[str, Any] | None = None) -> tuple[dict[str, Any], dict[str, Any]]:
task = self.task(task_id)
merged = {**task, **(payload or {}), "id": task_id}
node = self.schedule_node(merged)
node = self.select_compute_node(merged)
selected_gpus = merged.get("gpus") or [0]
return node, self._compute_job_payload_from_task_node(merged, node, selected_gpus)
def prepare_compute_job_payload_from_payload(self, payload: dict[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
task_id = str(payload.get("task_id") or payload.get("id") or new_id("ft_preview"))
name = str(payload.get("name") or task_id)
transient_task = {
**payload,
"id": task_id,
"name": name,
"status": str(payload.get("status") or "pending"),
"progress": int(payload.get("progress") or 0),
}
node = self.select_compute_node(transient_task)
selected_gpus = transient_task.get("gpus") or [0]
return node, self._compute_job_payload_from_task_node(transient_task, node, selected_gpus)
def _compute_job_payload_from_task_node(
self,
task: dict[str, Any],
node: dict[str, Any],
selected_gpus: list[int] | list[Any] | None = None,
) -> dict[str, Any]:
base_model_id = task.get("base_model") or task.get("model_id")
dataset_id = str(task.get("train_dataset_id") or task.get("dataset_id") or "")
with self.connect() as conn:
model = conn.execute("SELECT * FROM models WHERE id=?", (task.get("base_model"),)).fetchone()
dataset = conn.execute("SELECT * FROM datasets WHERE id=?", (task.get("train_dataset_id"),)).fetchone()
model = conn.execute("SELECT * FROM models WHERE id=?", (base_model_id,)).fetchone()
dataset = conn.execute("SELECT * FROM datasets WHERE id=?", (dataset_id,)).fetchone()
files = conn.execute(
"SELECT id, name, size, active_version_id, create_time FROM dataset_files WHERE dataset_id=? ORDER BY create_time",
(task.get("train_dataset_id"),),
(dataset_id,),
).fetchall()
model_path = (model and model.get("path")) or task.get("base_model")
dataset_id = str(task.get("train_dataset_id") or "")
model_path = (model and model.get("path")) or task.get("model_name_or_path") or base_model_id
if not files:
raise RuntimeError(f"dataset has no uploaded file: {dataset_id}")
dataset_key = str(task.get("dataset_key") or llama_dataset_key(dataset_id))
@@ -1897,6 +1912,10 @@ class PlatformStore:
raise RuntimeError("compute scheduler is busy, please retry")
return self._schedule_node_locked(conn, payload)
def select_compute_node(self, payload: dict[str, Any]) -> dict[str, Any]:
with self.connect() as conn:
return self._schedule_node_locked(conn, payload)
def _reserve_gpu_allocations(
self,
conn: PgConnection,