| from __future__ import annotations |
|
|
| from types import SimpleNamespace |
|
|
| from jarvis.runtime_turn import ( |
| attention_confidence, |
| classify_user_intent, |
| compute_turn_taking, |
| looks_like_user_correction, |
| requires_confirmation, |
| requires_stt_repair, |
| ) |
|
|
|
|
| def test_classify_user_intent_and_correction_detection() -> None: |
| assert classify_user_intent("Turn on the lights") == "action" |
| assert classify_user_intent("Can you turn on the lights and tell me the weather?") == "hybrid" |
| assert classify_user_intent("What time is it?") == "answer" |
| assert looks_like_user_correction("No, I meant the office lights.") is True |
| assert looks_like_user_correction("Thanks for the update.") is False |
|
|
|
|
| def test_attention_confidence_prioritizes_recent_signals() -> None: |
| signals = SimpleNamespace(face_last_seen=98.0, hand_last_seen=99.0, doa_last_seen=99.0) |
| assert attention_confidence(signals=signals, now=100.0, recency_sec=3.0) == 1.0 |
| signals = SimpleNamespace(face_last_seen=None, hand_last_seen=98.5, doa_last_seen=99.0) |
| assert attention_confidence(signals=signals, now=100.0, recency_sec=3.0) == 0.8 |
| signals = SimpleNamespace(face_last_seen=None, hand_last_seen=None, doa_last_seen=99.0) |
| assert attention_confidence(signals=signals, now=100.0, recency_sec=3.0) == 0.5 |
| assert attention_confidence(signals=None, now=100.0, recency_sec=3.0) == 0.0 |
|
|
|
|
| def test_compute_turn_taking_handles_busy_and_non_busy_paths() -> None: |
| assert compute_turn_taking( |
| 0.3, |
| False, |
| False, |
| attention=0.2, |
| turn_taking_threshold=0.6, |
| barge_in_threshold=0.5, |
| ) is False |
| assert compute_turn_taking( |
| 0.7, |
| True, |
| True, |
| attention=0.2, |
| turn_taking_threshold=0.6, |
| barge_in_threshold=0.65, |
| ) is True |
|
|
|
|
| def test_requires_stt_repair_low_confidence_and_fallback_cases() -> None: |
| assert requires_stt_repair( |
| "turn on the bedroom lights", |
| "action", |
| looks_like_correction=False, |
| diagnostics={"confidence_band": "low", "confidence_score": 0.4, "fallback_used": False}, |
| repair_min_words=3, |
| repair_confidence_threshold=0.55, |
| ) is True |
| assert requires_stt_repair( |
| "set the hallway lights to warm white", |
| "hybrid", |
| looks_like_correction=False, |
| diagnostics={"confidence_band": "unknown", "confidence_score": 0.0, "fallback_used": True}, |
| repair_min_words=3, |
| repair_confidence_threshold=0.55, |
| ) is True |
| assert requires_stt_repair( |
| "actually, I meant the kitchen", |
| "action", |
| looks_like_correction=True, |
| diagnostics={"confidence_band": "low", "confidence_score": 0.1, "fallback_used": True}, |
| repair_min_words=3, |
| repair_confidence_threshold=0.55, |
| ) is False |
|
|
|
|
| def test_requires_confirmation_applies_profile_thresholds() -> None: |
| assert requires_confirmation( |
| attention=0.2, |
| confirmations="minimal", |
| last_doa_speech=False, |
| intended_query_min_attention=0.35, |
| ) is False |
| assert requires_confirmation( |
| attention=0.2, |
| confirmations="strict", |
| last_doa_speech=True, |
| intended_query_min_attention=0.35, |
| ) is True |
| assert requires_confirmation( |
| attention=0.2, |
| confirmations="standard", |
| last_doa_speech=True, |
| intended_query_min_attention=0.35, |
| ) is False |
|
|