import json from services.shared.ai_context_summary import ( render_context_summary_text, update_context_summary_from_assistant_turn, update_context_summary_from_user_turn, ) def test_context_summary_tracks_city_and_branch_slot_for_schedule(): summary = update_context_summary_from_user_turn( None, channel="voice", language="ru", customer_name="Ернур", text="Мне нужен график работы в городе Алмата.", now="2026-04-12T00:00:00+00:00", ) assert summary["channel"] == "voice" assert summary["customer_name"] == "Ернур" assert summary["active_intent"] == "schedule" assert summary["confirmed_facts"]["city"] == "Алмата" assert summary["open_slots"] == ["branch_or_address"] def test_context_summary_maps_common_asr_city_mishearing_to_almaty(): summary = update_context_summary_from_user_turn( None, channel="voice", language="ru", customer_name="Ернур", text="Хочу узнать график работы.", now="2026-04-12T00:00:00+00:00", ) updated = update_context_summary_from_user_turn( json.dumps(summary, ensure_ascii=False), channel="voice", language="ru", customer_name="Ернур", text="Матта.", now="2026-04-12T00:00:02+00:00", ) assert updated["active_intent"] == "schedule" assert updated["confirmed_facts"]["city"] == "Алмата" assert updated["open_slots"] == ["branch_or_address"] def test_context_summary_does_not_overwrite_meaningful_request_with_low_signal(): summary = update_context_summary_from_user_turn( None, channel="voice", language="ru", customer_name="Ернур", text="Мне нужен график работы в городе Алмата.", now="2026-04-12T00:00:00+00:00", ) updated = update_context_summary_from_user_turn( json.dumps(summary, ensure_ascii=False), channel="voice", language="ru", customer_name="Ернур", text="Алло", now="2026-04-12T00:00:02+00:00", ) assert updated["active_request_text"] == "Мне нужен график работы в городе Алмата." assert updated["confirmed_facts"]["city"] == "Алмата" def test_context_summary_assistant_turn_keeps_slots_and_renders_text(): summary = update_context_summary_from_user_turn( None, channel="telegram", language="ru", customer_name="Клиент", text="Хочу узнать график работы в городе Алмата", now="2026-04-12T00:00:00+00:00", ) updated = update_context_summary_from_assistant_turn( json.dumps(summary, ensure_ascii=False), language="ru", customer_name="Клиент", reply_text="Подскажите, какой филиал или адрес в этом городе вас интересует?", decision_intent="clarification", needs_handoff=False, handoff_reason=None, now="2026-04-12T00:00:03+00:00", ) rendered = render_context_summary_text(updated) assert updated["open_slots"] == ["branch_or_address"] assert "city=Алмата" in rendered assert "график работы" in rendered def test_context_summary_generic_clarification_does_not_downgrade_specific_slot(): summary = update_context_summary_from_user_turn( None, channel="telegram", language="ru", customer_name="Клиент", text="Хочу узнать график работы в городе Алмата", now="2026-04-12T00:00:00+00:00", ) updated = update_context_summary_from_assistant_turn( json.dumps(summary, ensure_ascii=False), language="ru", customer_name="Клиент", reply_text="Уточните, пожалуйста, что именно нужно проверить или подсказать.", decision_intent="clarification", needs_handoff=False, handoff_reason=None, now="2026-04-12T00:00:03+00:00", ) assert updated["open_slots"] == ["branch_or_address"] assert updated["requested_clarifications"] == ["branch_or_address"]