feat: 手术视频消耗、待确认与持久化改造
- 新增 Alembic 初始迁移、领域明细模型及归档持久化与重试链路\n- 拆分视频会话注册表、分类处理、推理时间窗聚合与流处理\n- 消耗日志:TSV/Markdown 含 top2/top3;item_id 优先产品编码;待确认记「待确认」行,语音确认后落正式行并更新汇总\n- 待确认时内存/DB 明细为占位行,确认后替换;拒绝时移除占位\n- 分类 probs 先 detach/cpu 再转 NumPy,修复 MPS/CUDA 上推理被静默跳过\n- 补充集成测试、归档与设备张量等单测 Made-with: Cursor
This commit is contained in:
@@ -30,7 +30,7 @@ def test_live_consumption_requires_non_empty_details() -> None:
|
||||
)
|
||||
st = SurgerySessionState(candidate_consumables=["纱布"])
|
||||
run = RunningSurgery(stop_event=asyncio.Event(), state=st, tasks=[])
|
||||
mgr._active["123456"] = run
|
||||
mgr._registry._active["123456"] = run
|
||||
st.ready.set()
|
||||
assert mgr.live_consumption_if_active("123456") is None
|
||||
|
||||
@@ -59,7 +59,7 @@ async def test_resolve_voice_accepts_label_on_surgery_list_not_in_topk_options()
|
||||
model_top1_confidence=0.41,
|
||||
)
|
||||
st.pending_fifo.append(pid)
|
||||
mgr._active["123456"] = RunningSurgery(
|
||||
mgr._registry._active["123456"] = RunningSurgery(
|
||||
stop_event=asyncio.Event(), state=st, tasks=[]
|
||||
)
|
||||
|
||||
@@ -95,7 +95,7 @@ async def test_resolve_pending_appends_voice_detail() -> None:
|
||||
)
|
||||
st.pending_fifo.append(pid)
|
||||
run = RunningSurgery(stop_event=asyncio.Event(), state=st, tasks=[])
|
||||
mgr._active["123456"] = run
|
||||
mgr._registry._active["123456"] = run
|
||||
|
||||
await mgr.resolve_pending_confirmation(
|
||||
"123456", pid, chosen_label="纱布", rejected=False
|
||||
@@ -129,7 +129,7 @@ async def test_resolve_reject_closes_without_detail() -> None:
|
||||
model_top1_confidence=0.4,
|
||||
)
|
||||
st.pending_fifo.append(pid)
|
||||
mgr._active["123456"] = RunningSurgery(
|
||||
mgr._registry._active["123456"] = RunningSurgery(
|
||||
stop_event=asyncio.Event(), state=st, tasks=[]
|
||||
)
|
||||
|
||||
@@ -171,14 +171,10 @@ async def test_archive_retry_loop_starts() -> None:
|
||||
result_repository=None,
|
||||
)
|
||||
await mgr.start_archive_retry_loop()
|
||||
assert mgr._retry_task is not None
|
||||
mgr._retry_stop.set()
|
||||
mgr._retry_task.cancel()
|
||||
try:
|
||||
await mgr._retry_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
mgr._retry_task = None
|
||||
persister = mgr._archive
|
||||
assert persister._retry_task is not None
|
||||
await mgr.shutdown()
|
||||
assert persister._retry_task is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -242,9 +238,12 @@ async def test_handle_high_conf_top1_not_in_candidates_enqueues_pending() -> Non
|
||||
],
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert state.details == []
|
||||
assert len(state.details) == 1
|
||||
assert state.details[0].item_name == "待确认"
|
||||
assert state.details[0].source == "pending_confirmation"
|
||||
assert len(state.pending_fifo) == 1
|
||||
pid = state.pending_fifo[0]
|
||||
assert state.details[0].pending_confirmation_id == pid
|
||||
assert "缝线" in state.pending_by_id[pid].prompt_text
|
||||
|
||||
|
||||
@@ -270,6 +269,8 @@ async def test_handle_mid_confidence_enqueues_pending() -> None:
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert len(state.pending_fifo) == 1
|
||||
assert len(state.details) == 1
|
||||
assert state.details[0].item_name == "待确认"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -360,7 +361,7 @@ async def test_resolve_invalid_chosen_label() -> None:
|
||||
model_top1_confidence=0.4,
|
||||
)
|
||||
st.pending_fifo.append(pid)
|
||||
mgr._active["123456"] = RunningSurgery(
|
||||
mgr._registry._active["123456"] = RunningSurgery(
|
||||
stop_event=asyncio.Event(), state=st, tasks=[]
|
||||
)
|
||||
with pytest.raises(SurgeryPipelineError) as excinfo:
|
||||
@@ -407,7 +408,7 @@ async def test_resolve_second_time_not_found() -> None:
|
||||
model_top1_confidence=0.4,
|
||||
)
|
||||
st.pending_fifo.append(pid)
|
||||
mgr._active["123456"] = RunningSurgery(
|
||||
mgr._registry._active["123456"] = RunningSurgery(
|
||||
stop_event=asyncio.Event(), state=st, tasks=[]
|
||||
)
|
||||
await mgr.resolve_pending_confirmation(
|
||||
@@ -442,7 +443,7 @@ async def test_resolve_already_resolved_status() -> None:
|
||||
)
|
||||
st.pending_by_id[pid] = pending
|
||||
st.pending_fifo.append(pid)
|
||||
mgr._active["123456"] = RunningSurgery(
|
||||
mgr._registry._active["123456"] = RunningSurgery(
|
||||
stop_event=asyncio.Event(), state=st, tasks=[]
|
||||
)
|
||||
pending.status = "confirmed"
|
||||
|
||||
Reference in New Issue
Block a user