|
@@ -231,6 +231,7 @@ def test_chat_idle_timeout_exits_chat():
|
|
|
def test_chat_exit_phrase_exits_chat():
|
|
def test_chat_exit_phrase_exits_chat():
|
|
|
service, _, clock = _service()
|
|
service, _, clock = _service()
|
|
|
assert service.toggle_chat() is True
|
|
assert service.toggle_chat() is True
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
|
|
|
|
|
service.handle_event(_transcript(clock, "That's all."))
|
|
service.handle_event(_transcript(clock, "That's all."))
|
|
|
|
|
|
|
@@ -240,6 +241,7 @@ def test_chat_exit_phrase_exits_chat():
|
|
|
def test_exit_phrase_preserves_chat_history():
|
|
def test_exit_phrase_preserves_chat_history():
|
|
|
service, _, clock = _service()
|
|
service, _, clock = _service()
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
|
service.handle_event(_transcript(clock, "That's all."))
|
|
service.handle_event(_transcript(clock, "That's all."))
|
|
|
|
|
|
|
@@ -250,6 +252,7 @@ def test_exit_phrase_preserves_chat_history():
|
|
|
def test_viewer_detached_exits_chat_and_keeps_history():
|
|
def test_viewer_detached_exits_chat_and_keeps_history():
|
|
|
service, _, clock = _service()
|
|
service, _, clock = _service()
|
|
|
assert service.toggle_chat() is True
|
|
assert service.toggle_chat() is True
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
|
|
|
|
|
|
assert service.viewer_detached() is True
|
|
assert service.viewer_detached() is True
|
|
@@ -270,6 +273,7 @@ def test_exit_chat_preserves_history_and_does_not_reset():
|
|
|
cfg, FakeSubscriber(), time_fn=Clock(), chat_reset=lambda: resets.append(1)
|
|
cfg, FakeSubscriber(), time_fn=Clock(), chat_reset=lambda: resets.append(1)
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(Clock(), "hello"))
|
|
service.handle_event(_transcript(Clock(), "hello"))
|
|
|
|
|
|
|
|
service.viewer_detached()
|
|
service.viewer_detached()
|
|
@@ -282,6 +286,7 @@ def test_exit_chat_preserves_history_and_does_not_reset():
|
|
|
def test_chat_accumulates_turns():
|
|
def test_chat_accumulates_turns():
|
|
|
service, _, clock = _service()
|
|
service, _, clock = _service()
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
|
|
|
|
|
for text in ("hello there", "how are you"):
|
|
for text in ("hello there", "how are you"):
|
|
|
service.handle_event(_transcript(clock, text))
|
|
service.handle_event(_transcript(clock, text))
|
|
@@ -316,16 +321,16 @@ def test_chat_capture_off_still_allows_typed_turns_and_triage():
|
|
|
|
|
|
|
|
def test_set_chat_capture_emits_once_and_reports_status():
|
|
def test_set_chat_capture_emits_once_and_reports_status():
|
|
|
service, emitted, _ = _service()
|
|
service, emitted, _ = _service()
|
|
|
- assert service.status()["chat_capture"] is True
|
|
|
|
|
|
|
+ assert service.status()["chat_capture"] is False
|
|
|
|
|
|
|
|
- assert service.set_chat_capture(False) is True
|
|
|
|
|
|
|
+ assert service.set_chat_capture(True) is True
|
|
|
assert [e for e in emitted if e["type"] == "chat_capture"] == [
|
|
assert [e for e in emitted if e["type"] == "chat_capture"] == [
|
|
|
- {"type": "chat_capture", "on": False}
|
|
|
|
|
|
|
+ {"type": "chat_capture", "on": True}
|
|
|
]
|
|
]
|
|
|
- assert service.status()["chat_capture"] is False
|
|
|
|
|
|
|
+ assert service.status()["chat_capture"] is True
|
|
|
|
|
|
|
|
emitted.clear()
|
|
emitted.clear()
|
|
|
- service.set_chat_capture(False)
|
|
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
assert emitted == []
|
|
assert emitted == []
|
|
|
|
|
|
|
|
|
|
|
|
@@ -341,6 +346,7 @@ def test_triage_chat_off_ignores_chat_turns():
|
|
|
def test_triage_chat_sends_reply_only_when_capture_on():
|
|
def test_triage_chat_sends_reply_only_when_capture_on():
|
|
|
service, _, _, _, lane = _triage_service()
|
|
service, _, _, _, lane = _triage_service()
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.set_triage_chat(True)
|
|
service.set_triage_chat(True)
|
|
|
|
|
|
|
|
service._run_chat("spoken, already in triage")
|
|
service._run_chat("spoken, already in triage")
|
|
@@ -513,6 +519,7 @@ def test_pending_chat_is_not_lost_across_threads():
|
|
|
|
|
|
|
|
service = AssistantService(cfg, FakeSubscriber(), emit=emit, chat_fn=lambda text: "ok")
|
|
service = AssistantService(cfg, FakeSubscriber(), emit=emit, chat_fn=lambda text: "ok")
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.start()
|
|
service.start()
|
|
|
try:
|
|
try:
|
|
|
total = 200
|
|
total = 200
|
|
@@ -630,6 +637,7 @@ def test_chat_notify_emits_truncated_error():
|
|
|
def test_clear_empties_chat_history():
|
|
def test_clear_empties_chat_history():
|
|
|
service, emitted, clock = _service()
|
|
service, emitted, clock = _service()
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
|
|
|
|
|
for text in ("hello", "how are you"):
|
|
for text in ("hello", "how are you"):
|
|
|
service.handle_event(_transcript(clock, text))
|
|
service.handle_event(_transcript(clock, text))
|
|
@@ -1352,6 +1360,7 @@ def test_none_payload_dispatches_nothing_and_keeps_deltas():
|
|
|
brief_fn=lambda prompt: calls.append(prompt) or "RAW"
|
|
brief_fn=lambda prompt: calls.append(prompt) or "RAW"
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1371,6 +1380,7 @@ def test_none_payload_dispatches_nothing_and_keeps_deltas():
|
|
|
def test_none_payload_without_brief_fn_enqueues_nothing():
|
|
def test_none_payload_without_brief_fn_enqueues_nothing():
|
|
|
service, emitted, clock, _, lane = _triage_service()
|
|
service, emitted, clock, _, lane = _triage_service()
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1406,6 +1416,7 @@ def test_substantive_turn_dispatches_one_brief_job():
|
|
|
triage=FakeTriage(escalate=True), brief_fn=lambda prompt: "RAW"
|
|
triage=FakeTriage(escalate=True), brief_fn=lambda prompt: "RAW"
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "we might churn"))
|
|
service.handle_event(_transcript(clock, "we might churn"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1429,6 +1440,7 @@ def test_substantive_turn_dispatches_one_brief_job():
|
|
|
def test_brief_dispatches_without_escalation():
|
|
def test_brief_dispatches_without_escalation():
|
|
|
service, _, clock, _, lane = _triage_service(brief_fn=lambda prompt: "RAW")
|
|
service, _, clock, _, lane = _triage_service(brief_fn=lambda prompt: "RAW")
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "all calm"))
|
|
service.handle_event(_transcript(clock, "all calm"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1451,6 +1463,7 @@ def test_gated_out_turn_skips_brief():
|
|
|
brief_fn=lambda prompt: calls.append(prompt) or "RAW",
|
|
brief_fn=lambda prompt: calls.append(prompt) or "RAW",
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "small talk"))
|
|
service.handle_event(_transcript(clock, "small talk"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1504,6 +1517,7 @@ def test_gated_out_turn_retains_brief_when_extract_disabled():
|
|
|
triage=FakeTriage(gate=False), brief_fn=lambda prompt: "RAW"
|
|
triage=FakeTriage(gate=False), brief_fn=lambda prompt: "RAW"
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
signals = _escalated_payload()
|
|
signals = _escalated_payload()
|
|
|
service._last_brief_signals = signals
|
|
service._last_brief_signals = signals
|
|
|
token = _seed_brief(service, "Unknown: first")
|
|
token = _seed_brief(service, "Unknown: first")
|
|
@@ -1578,6 +1592,7 @@ def test_no_brief_when_disabled_in_config():
|
|
|
)
|
|
)
|
|
|
service.cfg.triage.extract_enabled = False
|
|
service.cfg.triage.extract_enabled = False
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "churn risk"))
|
|
service.handle_event(_transcript(clock, "churn risk"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1594,6 +1609,7 @@ def test_no_brief_when_disabled_in_config():
|
|
|
def test_no_brief_without_brief_fn():
|
|
def test_no_brief_without_brief_fn():
|
|
|
service, _, clock, _, lane = _triage_service(triage=FakeTriage(escalate=True))
|
|
service, _, clock, _, lane = _triage_service(triage=FakeTriage(escalate=True))
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "churn risk"))
|
|
service.handle_event(_transcript(clock, "churn risk"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1613,6 +1629,7 @@ def test_brief_refused_when_queue_full():
|
|
|
)
|
|
)
|
|
|
service._inference = InferenceQueue(size=2)
|
|
service._inference = InferenceQueue(size=2)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "churn risk"))
|
|
service.handle_event(_transcript(clock, "churn risk"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1634,6 +1651,7 @@ def test_second_result_while_outstanding_is_refused():
|
|
|
"""At most one brief job is outstanding: the second turn only stores signals."""
|
|
"""At most one brief job is outstanding: the second turn only stores signals."""
|
|
|
service, emitted, clock, _, lane = _triage_service(brief_fn=lambda prompt: "RAW")
|
|
service, emitted, clock, _, lane = _triage_service(brief_fn=lambda prompt: "RAW")
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "first"))
|
|
service.handle_event(_transcript(clock, "first"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -1903,6 +1921,7 @@ def test_clear_resets_triage():
|
|
|
chat_reset=lambda: chats.append(1),
|
|
chat_reset=lambda: chats.append(1),
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "churn"))
|
|
service.handle_event(_transcript(clock, "churn"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -2044,6 +2063,7 @@ def test_stale_brief_after_clear_does_not_clear_newer_dispatch_flag():
|
|
|
brief_fn=lambda prompt: "RAW", brief_file=brief_file
|
|
brief_fn=lambda prompt: "RAW", brief_file=brief_file
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -2101,6 +2121,7 @@ def test_triage_end_to_end_signals_content_cleared():
|
|
|
brief_fn=lambda prompt: prompts.append(prompt) or "the brief"
|
|
brief_fn=lambda prompt: prompts.append(prompt) or "the brief"
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
|
|
|
|
|
service.handle_event(_transcript(clock, "first thought"))
|
|
service.handle_event(_transcript(clock, "first thought"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
@@ -2315,6 +2336,7 @@ def _dump_brief(prompt, on_io=None, finalize=None):
|
|
|
|
|
|
|
|
def _run_triage_flow(service, emitted, clock, lane, payload):
|
|
def _run_triage_flow(service, emitted, clock, lane, payload):
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
clock.advance(service.cfg.assistant.turn_gap_s + 0.1)
|
|
|
service.tick()
|
|
service.tick()
|
|
@@ -2683,6 +2705,7 @@ def test_live_session_change_resets_triage_and_keeps_chat():
|
|
|
brief_file=brief_file, brief_reset=lambda: resets.append(1)
|
|
brief_file=brief_file, brief_reset=lambda: resets.append(1)
|
|
|
)
|
|
)
|
|
|
service.toggle_chat()
|
|
service.toggle_chat()
|
|
|
|
|
+ service.set_chat_capture(True)
|
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
service.handle_event(_transcript(clock, "hello"))
|
|
|
service.handle_event(_session_event(clock, "transcripts/a"))
|
|
service.handle_event(_session_event(clock, "transcripts/a"))
|
|
|
service.last_triage = {"signals": 1}
|
|
service.last_triage = {"signals": 1}
|