feat: 语音确认、联调与运维增强
- 语音:序数解析(第一个/第二个等)、解析失败计数与 API detail.retry_remaining; 百度 ASR 固定 dev_pid 为普通话;SurgeryPipelineError 支持 extra 并入 HTTP detail。 - Demo:demo 路由与假 RTSP、客户端 index 与 README;BackendResolver 与配置调整。 - 可观测:消耗 TSV 日志、语音文件日志、终端 Markdown 辅助;相关测试与依赖更新。 - 注意:.env 仍被 gitignore,本地密钥不会进入本提交。 Made-with: Cursor
This commit is contained in:
@@ -156,9 +156,7 @@ async def test_handle_skips_when_candidate_list_empty() -> None:
|
||||
confidence=0.99,
|
||||
topk=[PredictionCandidate(label="纱布", confidence=0.99)],
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert state.details == []
|
||||
assert state.pending_fifo == []
|
||||
|
||||
@@ -199,9 +197,7 @@ async def test_handle_skips_below_voice_floor() -> None:
|
||||
confidence=0.4,
|
||||
topk=[PredictionCandidate(label="纱布", confidence=0.4)],
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert state.details == []
|
||||
assert state.pending_fifo == []
|
||||
|
||||
@@ -221,9 +217,7 @@ async def test_handle_auto_vision_confirm() -> None:
|
||||
confidence=0.99,
|
||||
topk=[PredictionCandidate(label="纱布", confidence=0.99)],
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert len(state.details) == 1
|
||||
assert state.details[0].source == "vision"
|
||||
assert state.details[0].item_id == "纱布"
|
||||
@@ -247,9 +241,7 @@ async def test_handle_high_conf_top1_not_in_candidates_enqueues_pending() -> Non
|
||||
PredictionCandidate(label="缝线", confidence=0.2),
|
||||
],
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert state.details == []
|
||||
assert len(state.pending_fifo) == 1
|
||||
pid = state.pending_fifo[0]
|
||||
@@ -276,9 +268,7 @@ async def test_handle_mid_confidence_enqueues_pending() -> None:
|
||||
PredictionCandidate(label="缝线", confidence=0.3),
|
||||
],
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert len(state.pending_fifo) == 1
|
||||
|
||||
|
||||
@@ -299,9 +289,7 @@ async def test_handle_voice_disabled_no_pending_for_mid_conf() -> None:
|
||||
confidence=0.5,
|
||||
topk=[PredictionCandidate(label="纱布", confidence=0.5)],
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert state.pending_fifo == []
|
||||
assert state.details == []
|
||||
|
||||
@@ -322,12 +310,8 @@ async def test_handle_vision_cooldown_skips_duplicate() -> None:
|
||||
confidence=0.99,
|
||||
topk=[PredictionCandidate(label="纱布", confidence=0.99)],
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert len(state.details) == 1
|
||||
|
||||
|
||||
@@ -350,12 +334,8 @@ async def test_handle_pending_dedupe_cooldown() -> None:
|
||||
PredictionCandidate(label="缝线", confidence=0.2),
|
||||
],
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(
|
||||
state=state, cls_res=res
|
||||
)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
await mgr._handle_classification_result(state=state, cls_res=res)
|
||||
assert len(state.pending_fifo) == 1
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user