feat(training): release V0.9.1 避障训练与基础策略迁移
This commit is contained in:
@@ -12,6 +12,8 @@ from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from .schema import FLAT_TASK, RewardConfigError, validate_configuration
|
||||
|
||||
SCHEMA_VERSION = 2
|
||||
|
||||
|
||||
@@ -169,16 +171,37 @@ class TuningStorage:
|
||||
def recover_interrupted(self) -> None:
|
||||
at = now_iso()
|
||||
with self.transaction() as connection:
|
||||
previous = connection.execute(
|
||||
"SELECT id,state FROM sessions WHERE state IN "
|
||||
"('queued','running','evaluating','paused','awaiting_approval')"
|
||||
).fetchall()
|
||||
for row in previous:
|
||||
connection.execute(
|
||||
"INSERT INTO audit_events(session_id,event_type,payload_json,created_at) "
|
||||
"VALUES (?,?,?,?)",
|
||||
(
|
||||
row["id"],
|
||||
"service_restart_interrupted",
|
||||
_json(
|
||||
{
|
||||
"previousState": row["state"],
|
||||
"reason": "service_restart",
|
||||
"requiresExplicitResume": True,
|
||||
}
|
||||
),
|
||||
at,
|
||||
),
|
||||
)
|
||||
connection.execute(
|
||||
"UPDATE trials SET state='interrupted', ended_at=?, "
|
||||
"message='服务重启中断,等待显式恢复' "
|
||||
"WHERE state IN ('training','evaluating')",
|
||||
"WHERE state IN ('queued','training','evaluating')",
|
||||
(at,),
|
||||
)
|
||||
connection.execute(
|
||||
"UPDATE sessions SET state='interrupted', updated_at=?, "
|
||||
"message='服务重启中断,可从完整 checkpoint 恢复' "
|
||||
"WHERE state IN ('running','evaluating')",
|
||||
"WHERE state IN ('queued','running','evaluating','paused','awaiting_approval')",
|
||||
(at,),
|
||||
)
|
||||
|
||||
@@ -643,47 +666,51 @@ class TuningStorage:
|
||||
for row in rows
|
||||
]
|
||||
|
||||
def _preset_task(self, session_id: str) -> str:
|
||||
# Identity comes only from the persisted source session, never client/preset labels.
|
||||
try:
|
||||
config = self.get_session(session_id)["config"]
|
||||
except (KeyError, ValueError, TypeError) as error:
|
||||
raise RewardConfigError("奖励 preset 来源 session 丢失或损坏") from error
|
||||
if not isinstance(config, dict):
|
||||
raise RewardConfigError("奖励 preset 来源 config 必须是对象")
|
||||
# Original Flat-only sessions did not require taskId. Validate their preset below.
|
||||
return config.get("taskId", FLAT_TASK)
|
||||
|
||||
def _preset(self, row) -> dict:
|
||||
task_id = self._preset_task(row["session_id"])
|
||||
try:
|
||||
reward_config = validate_configuration(_decode(row["reward_config_json"]), task_id)
|
||||
except (ValueError, TypeError) as error:
|
||||
raise RewardConfigError("奖励 preset 配置无效:" + str(error)) from error
|
||||
return {
|
||||
"id": row["id"],
|
||||
"name": row["name"],
|
||||
"sessionId": row["session_id"],
|
||||
"trialId": row["trial_id"],
|
||||
"taskId": task_id,
|
||||
"rewardConfig": reward_config,
|
||||
"createdAt": row["created_at"],
|
||||
}
|
||||
|
||||
def save_preset(self, name: str, session_id: str, trial_id: str, reward_config: dict) -> dict:
|
||||
reward_config = validate_configuration(reward_config, self._preset_task(session_id))
|
||||
preset_id, at = uuid.uuid4().hex, now_iso()
|
||||
self.connection().execute(
|
||||
"INSERT INTO presets(id,name,session_id,trial_id,reward_config_json,created_at) "
|
||||
"VALUES (?,?,?,?,?,?)",
|
||||
(preset_id, name, session_id, trial_id, _json(reward_config), at),
|
||||
)
|
||||
return {
|
||||
"id": preset_id,
|
||||
"name": name,
|
||||
"sessionId": session_id,
|
||||
"trialId": trial_id,
|
||||
"rewardConfig": reward_config,
|
||||
"createdAt": at,
|
||||
}
|
||||
return self.get_preset(preset_id)
|
||||
|
||||
def get_preset(self, preset_id: str) -> dict:
|
||||
row = self.connection().execute("SELECT * FROM presets WHERE id=?", (preset_id,)).fetchone()
|
||||
if row is None:
|
||||
raise KeyError(preset_id)
|
||||
return {
|
||||
"id": row["id"],
|
||||
"name": row["name"],
|
||||
"sessionId": row["session_id"],
|
||||
"trialId": row["trial_id"],
|
||||
"rewardConfig": _decode(row["reward_config_json"]),
|
||||
"createdAt": row["created_at"],
|
||||
}
|
||||
return self._preset(row)
|
||||
|
||||
def list_presets(self) -> list[dict]:
|
||||
rows = (
|
||||
self.connection().execute("SELECT * FROM presets ORDER BY created_at DESC").fetchall()
|
||||
)
|
||||
return [
|
||||
{
|
||||
"id": row["id"],
|
||||
"name": row["name"],
|
||||
"sessionId": row["session_id"],
|
||||
"trialId": row["trial_id"],
|
||||
"rewardConfig": _decode(row["reward_config_json"]),
|
||||
"createdAt": row["created_at"],
|
||||
}
|
||||
for row in rows
|
||||
]
|
||||
return [self._preset(row) for row in rows]
|
||||
|
||||
Reference in New Issue
Block a user