feat(ml): lease announces detector config; agent builds proposers from it live (#134 step 2)
The GPU lease now carries the crop-proposer config from MLSettings in a per-job 'detectors' block (same pattern as embed_model_name). The agent's worker builds its Proposers from the announced config via _effective_cfg (lease block overlaid on env) + _proposers_for (rebuilds only when a config signature changes) — so an operator's UI edit takes effect on the next lease with NO restart, and env is now just the bootstrap fallback until the server announces. enabled-off maps to empty weights (proposer skipped); dedupe_iou + max_regions also come from the effective cfg. Test: lease announces the detectors block with the seeded default weights. 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:
@@ -105,6 +105,30 @@ async def test_lease_announces_embed_model_then_submit_embedding(client, db):
|
||||
assert img.siglip_embedding is not None and len(list(img.siglip_embedding)) == 1152
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_lease_announces_detector_config(client, db):
|
||||
# #134: the lease carries the crop-proposer config from MLSettings, so the
|
||||
# agent builds its detectors from the DB/UI (no restart). Defaults are all-on
|
||||
# with the pinned working weights.
|
||||
img = await _img(db, "c" * 64)
|
||||
await GpuJobService(db).enqueue(img.id, "embed")
|
||||
await db.commit()
|
||||
token = (await (await client.post("/api/gpu/token/rotate")).get_json())["token"]
|
||||
hdr = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
leased = await client.post(
|
||||
"/api/gpu/jobs/lease", json={"agent_id": "a1", "batch_size": 5}, headers=hdr,
|
||||
)
|
||||
det = (await leased.get_json())["jobs"][0]["detectors"]
|
||||
assert det["person"]["enabled"]
|
||||
assert det["anatomy"]["enabled"]
|
||||
assert det["panel"]["enabled"]
|
||||
assert "yolov11m_aa22" in det["anatomy"]["weights"] # booru_yolo default
|
||||
assert det["panel"]["weights"].endswith("::best.pt") # mosesb default
|
||||
assert det["max_regions"] == 128
|
||||
assert det["dedupe_iou"] == 0.85
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_submit_with_stale_lease_is_409(client, db):
|
||||
img = await _img(db, "b" * 64)
|
||||
|
||||
Reference in New Issue
Block a user