feat(ml): Settings → Tagging 'Crop proposers' card (#134 step 3)
Exposes the detector config (per-proposer enable + weights + confidence, caps, dedupe IoU) in Settings → Tagging, backed by MLSettings via /api/ml/settings. ml_admin adds the detector fields to _EDITABLE + GET payload + validation (conf 0..1, caps >=1, IoU 0..1). New CropProposersCard.vue (mirrors HeadsCard) with working defaults pre-filled, per-field live-save (no restart — the agent picks changes up on its next lease), weights-format help, switch-revert on error. Closes milestone #134: all three proposers are on out-of-the-box and tunable in the UI. Test: detector defaults GET + patch round-trip + range validation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnM
This commit is contained in:
@@ -52,6 +52,35 @@ async def test_embedder_model_default_settable_and_empty_rejected(client):
|
||||
assert bad.status_code == 400
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_detector_settings_defaults_patch_and_validation(client):
|
||||
# #134: crop-proposer config is exposed + editable here (announced to the
|
||||
# agent via the lease). Defaults are all-on with the pinned weights.
|
||||
body = await (await client.get("/api/ml/settings")).get_json()
|
||||
assert body["detector_person_enabled"] is True
|
||||
assert body["detector_anatomy_enabled"] is True
|
||||
assert "yolov11m_aa22" in body["detector_anatomy_weights"]
|
||||
assert body["detector_panel_weights"].endswith("::best.pt")
|
||||
assert body["detector_max_regions"] == 128
|
||||
|
||||
ok = await client.patch("/api/ml/settings", json={
|
||||
"detector_anatomy_enabled": False,
|
||||
"detector_person_conf": 0.5,
|
||||
"detector_max_panels": 4,
|
||||
})
|
||||
assert ok.status_code == 200
|
||||
out = await ok.get_json()
|
||||
assert out["detector_anatomy_enabled"] is False
|
||||
assert out["detector_person_conf"] == 0.5
|
||||
assert out["detector_max_panels"] == 4
|
||||
|
||||
# Out-of-range confidence + non-positive cap are rejected.
|
||||
assert (await client.patch(
|
||||
"/api/ml/settings", json={"detector_panel_conf": 1.5})).status_code == 400
|
||||
assert (await client.patch(
|
||||
"/api/ml/settings", json={"detector_max_regions": 0})).status_code == 400
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_embedder_models_list(client):
|
||||
# #1203: the dropdown reads the supported-model list from the server.
|
||||
|
||||
Reference in New Issue
Block a user