feat(tuning): release V0.8.2 Agent 界面重构
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled

This commit is contained in:
2026-09-03 16:25:53 +08:00
parent a9b07e0abf
commit 63d67a645b
35 changed files with 4847 additions and 811 deletions
@@ -148,6 +148,8 @@ class TuningManagerTest(unittest.TestCase):
self.fail("session did not wait for approval")
proposal = detail["proposals"][-1]
patch = {"weights": {"pose": 1.1}, "params": {}}
with self.assertRaisesRegex(Exception, "feedback"):
self.manager.approve(session["id"], proposal["id"], {"feedback": {}})
approved = self.manager.approve(
session["id"], proposal["id"], {"feedback": "ok", "patch": patch}
)
@@ -155,6 +157,34 @@ class TuningManagerTest(unittest.TestCase):
self.manager.cancel(session["id"])
self.assertEqual(self.wait_terminal(session["id"])["state"], "cancelled")
def test_runtime_mode_switch_auto_approves_pending_proposal(self):
session = self.manager.create(self.payload("approval"))
deadline = time.monotonic() + 3
while time.monotonic() < deadline:
detail = self.manager.detail(session["id"])
if detail["state"] == "awaiting_approval":
break
time.sleep(0.01)
else:
self.fail("session did not wait for approval")
changed = self.manager.set_mode(session["id"], {"mode": "automatic"})
self.assertEqual(changed["mode"], "automatic")
self.assertEqual(changed["proposals"][-1]["state"], "approved")
completed = self.wait_terminal(session["id"])
self.assertEqual(completed["state"], "succeeded", completed["message"])
def test_trial_count_is_user_configurable(self):
payload = self.payload()
payload["trialCount"] = 1
_, config, _, _ = self.manager.parse_create(payload)
self.assertEqual(config["trialCount"], 1)
payload["trialCount"] = 100
_, config, _, _ = self.manager.parse_create(payload)
self.assertEqual(config["trialCount"], 100)
payload["trialCount"] = 101
with self.assertRaisesRegex(Exception, "trialCount"):
self.manager.parse_create(payload)
def test_resume_discards_only_interrupted_trial_and_continues(self):
mode, config, objective, fallback = self.manager.parse_create(self.payload())
session = self.manager.storage.create_session(mode, config, objective, fallback)
@@ -178,8 +208,10 @@ class TuningManagerTest(unittest.TestCase):
"trial-001-rung-0",
)
self.manager.storage.update_trial(interrupted["id"], state="interrupted")
self.manager.storage.reset_step_gate(session["id"])
self.manager.storage.update_session(session["id"], state="interrupted")
self.manager.resume(session["id"])
self.assertEqual(self.manager.storage.get_control(session["id"])["runPolicy"], "continuous")
completed = self.wait_terminal(session["id"])
self.assertEqual(completed["state"], "succeeded", completed["message"])
self.assertNotIn(interrupted["id"], [trial["id"] for trial in completed["trials"]])
@@ -190,6 +222,129 @@ class TuningManagerTest(unittest.TestCase):
self.manager.parse_create({"taskId": "Other"})
self.assertEqual(self.manager.test_agent()["model"], "fake")
def test_pause_closes_persistent_dispatch_gate_at_trial_boundary(self):
mode, config, objective, fallback = self.manager.parse_create(self.payload())
session = self.manager.storage.create_session(mode, config, objective, fallback)
self.manager.storage.update_session(session["id"], state="running")
self.manager.storage.grant_dispatch_token(session["id"])
paused = self.manager.pause(session["id"])
self.assertEqual(paused["state"], "paused")
self.assertEqual(paused["control"]["runPolicy"], "step")
self.assertEqual(paused["control"]["dispatchTokens"], 0)
def test_step_token_executes_exactly_one_trial_then_pauses(self):
session = self.manager.create(self.payload("approval"))
deadline = time.monotonic() + 3
while time.monotonic() < deadline:
detail = self.manager.detail(session["id"])
if detail["state"] == "awaiting_approval":
break
time.sleep(0.01)
else:
self.fail("session did not wait for approval")
baseline_count = len([trial for trial in detail["trials"] if trial["state"] == "completed"])
stepped = self.manager.step(session["id"], {"count": 1})
self.assertEqual(stepped["control"]["runPolicy"], "step")
self.assertEqual(stepped["control"]["dispatchTokens"], 1)
proposal = stepped["proposals"][-1]
self.manager.approve(session["id"], proposal["id"], {})
deadline = time.monotonic() + 3
while time.monotonic() < deadline:
detail = self.manager.detail(session["id"])
completed_count = len(
[trial for trial in detail["trials"] if trial["state"] == "completed"]
)
if detail["state"] == "paused" and completed_count == baseline_count + 1:
break
time.sleep(0.01)
else:
self.fail("single-step trial did not pause at the next boundary")
time.sleep(0.05)
self.assertEqual(
len(
[
trial
for trial in self.manager.detail(session["id"])["trials"]
if trial["state"] == "completed"
]
),
baseline_count + 1,
)
self.manager.cancel(session["id"])
self.assertEqual(self.wait_terminal(session["id"])["state"], "cancelled")
def test_constraints_are_revisioned_and_enforced_during_approval(self):
session = self.manager.create(self.payload("approval"))
deadline = time.monotonic() + 3
while time.monotonic() < deadline:
detail = self.manager.detail(session["id"])
if detail["state"] == "awaiting_approval":
break
time.sleep(0.01)
else:
self.fail("session did not wait for approval")
proposal = detail["proposals"][-1]
constrained = self.manager.set_constraints(
session["id"],
{
"revision": 0,
"constraints": {"weights.track_linear_velocity": {"kind": "fixed", "value": 1.0}},
},
)
self.assertEqual(constrained["control"]["constraintsRevision"], 1)
with self.assertRaisesRegex(Exception, "已固定"):
self.manager.approve(
session["id"],
proposal["id"],
{"patch": {"weights": {"track_linear_velocity": 1.1}, "params": {}}},
)
with self.assertRaisesRegex(Exception, "revision"):
self.manager.set_constraints(session["id"], {"revision": 0, "constraints": {}})
self.manager.approve(session["id"], proposal["id"], {})
self.manager.cancel(session["id"])
self.assertEqual(self.wait_terminal(session["id"])["state"], "cancelled")
def test_rollback_uses_safe_completed_trial_as_next_proposal_base(self):
session = self.manager.create(self.payload("approval"))
deadline = time.monotonic() + 3
while time.monotonic() < deadline:
detail = self.manager.detail(session["id"])
if detail["state"] == "awaiting_approval":
break
time.sleep(0.01)
else:
self.fail("session did not wait for approval")
baseline = detail["trials"][0]
old_proposal = detail["proposals"][-1]
rolled_back = self.manager.rollback(
session["id"], {"trialId": baseline["id"], "checkpoint": True}
)
self.assertEqual(rolled_back["state"], "paused")
self.assertEqual(rolled_back["control"]["activeBaseTrialId"], baseline["id"])
self.assertEqual(
next(item for item in rolled_back["proposals"] if item["id"] == old_proposal["id"])[
"state"
],
"rejected",
)
self.manager.step(session["id"], {"count": 1})
deadline = time.monotonic() + 3
while time.monotonic() < deadline:
detail = self.manager.detail(session["id"])
if (
detail["state"] == "awaiting_approval"
and detail["proposals"][-1]["id"] != old_proposal["id"]
):
break
time.sleep(0.01)
else:
self.fail("rollback base did not produce a replacement proposal")
self.assertEqual(detail["proposals"][-1]["baseTrialId"], baseline["id"])
self.manager.cancel(session["id"])
self.assertEqual(self.wait_terminal(session["id"])["state"], "cancelled")
if __name__ == "__main__":
unittest.main()